Every exam has multiple construction questions across Q1–Q6. Which models are tested varies, but DFA + at least one other is guaranteed.
Types tested on the 24–25 exams:
Given DFAs D1 = (Q1, Σ, δ1, q01, F1) and D2 = (Q2, Σ, δ2, q02, F2):
Build D = (Q1 × Q2, Σ, δ, (q01, q02), F) where:
DFA D: states {q0, q1, q2}, Σ = {a, b, c}, q0 start, F = {q0, q2}.
| State | a | b | c |
|---|---|---|---|
| q0 | q0 | q1 | q1 |
| q1 | q1 | q2 | q1 |
| q2 | q1 | q1 | q2 |
DFA D′: states {q3, q4}, Σ = {a, b}, q3 start, F′ = {q3}.
| State | a | b |
|---|---|---|
| q3 | q4 | q3 |
| q4 | q3 | q3 |
Build D″ with L(D″) = L(D) ∩ L(D′). Since Σ for D′ is {a, b}, D′ has no c-transitions — only a and b symbols are in L(D′), so the intersection only contains words over {a, b}.
Product construction
Start state: (q0, q3). Accept states F = F_D × F_D′ = {(q0, q3), (q2, q3)}.
Build the reachable states only (transitions on a and b since those are the shared alphabet):
| State | a | b |
|---|---|---|
| (q0, q3) ✓ | (q0, q4) | (q1, q3) |
| (q0, q4) | (q0, q3) | (q1, q3) |
| (q1, q3) | (q1, q4) | (q2, q3) |
| (q1, q4) | (q1, q3) | (q2, q3) |
| (q2, q3) ✓ | (q1, q4) | (q1, q3) |
5 reachable states. (q2, q4) is never reached. Accept states marked with ✓.
D1: states {p0, p1}, Σ = {0, 1}, p0 start, F1 = {p1}. Transitions: p0 ⟶0 p0, p0 ⟶1 p1, p1 ⟶0 p0, p1 ⟶1 p1.
D2: states {r0, r1}, Σ = {0, 1}, r0 start, F2 = {r0}. Transitions: r0 ⟶0 r1, r0 ⟶1 r0, r1 ⟶0 r0, r1 ⟶1 r1.
Construct D with L(D) = L(D1) ∪ L(D2). Give the transition table and accept states.
L(D1) = “ends with 1”. L(D2) = “even number of 0’s”. Union: ends with 1 OR even number of 0’s.
Start: (p0, r0). F = (F1 × Q2) ∪ (Q1 × F2) = {(p1, r0), (p1, r1), (p0, r0), (p1, r0)} = {(p0, r0), (p1, r0), (p1, r1)}.
| State | 0 | 1 |
|---|---|---|
| (p0, r0) ✓ | (p0, r1) | (p1, r0) |
| (p0, r1) | (p0, r0) | (p1, r1) |
| (p1, r0) ✓ | (p0, r1) | (p1, r0) |
| (p1, r1) ✓ | (p0, r0) | (p1, r1) |
4 states, all reachable. Only (p0, r1) is non-accepting (ends with 0 AND odd number of 0’s).
Kleene Star (L*):
Reverse (LR):
Union (L1 ∪ L2) and Concatenation (L1 · L2):
Given DFA D with L(D) = “even number of b’s, ≥ 1”. Construct NFA N with L(N) = L(D)*.
Construction
The new NFA accepts: ε, one copy of L(D), two copies concatenated, etc. — that’s exactly L(D)*.
Given NFA N with 4 states {q0, q1, q2, q3}, q0 start, accept states {q2, q3}. Construct N′ with L(N′) = {wR | w ∈ L(N)}.
Construction
The resulting NFA reads the reversed word: it starts where the original accepted and traces backwards to where the original started.
N1 accepts L1 = {an | n ≥ 1}. N2 accepts L2 = {bn | n ≥ 1}. Construct an NFA for L1 · L2 = {ambn | m, n ≥ 1}.
N1: q0 ⟶a q1 (q1 accepting, self-loop on a). N2: r0 ⟶b r1 (r1 accepting, self-loop on b).
Concatenation: add ε from q1 to r0. Remove q1 as accept state. Accept state: r1 only.
Result: q0 ⟶a q1 ⟶ε r0 ⟶b r1, with self-loops a on q1 and b on r1.
DFA D: states {q0, q1}, Σ = {0, 1}, q0 start, F = {q1}. Transitions: q0 ⟶0 q0, q0 ⟶1 q1, q1 ⟶0 q1, q1 ⟶1 q0.
(a) Construct NFA for L(D)R. (b) Apply subset construction to convert back to DFA.
(a) Reverse NFA:
Original transitions: q0 ⟶0 q0, q0 ⟶1 q1, q1 ⟶0 q1, q1 ⟶1 q0.
Reversed transitions: q0 ⟶0 q0, q0 ⟶1 q1, q1 ⟶0 q1, q1 ⟶1 q0. (Identical — this automaton is symmetric.)
Add new start qs with ε to q1 (old accept). New accept state: q0 (old start).
(b) Subset construction:
Start: E({qs}) = {qs, q1}.
{qs, q1} on 0: δ(q1, 0) = {q1}. → {q1}.
{qs, q1} on 1: δ(q1, 1) = {q0}. → {q0}. ✓
{q1} on 0: {q1}. On 1: {q0}. ✓
{q0} on 0: {q0}. ✓ On 1: {q1}.
DFA: 3 states. Start: {qs, q1}. Accept states: {q0} (contains old start q0).
L(D) = “odd number of 1’s” which equals its own reverse, so L(D)R = L(D).
1. Start state = ε-closure of NFA start: E({q0})
2. For each state set S and symbol a:
new state = E( ∪_{q ∈ S} δ(q, a) )
3. Accept states = any set containing an NFA accept state
4. Leave out unreachable states
NFA N: states {q0, q1, q2}, Σ = {0, 1}, q0 start, F = {q2}.
| State | 0 | 1 | ε |
|---|---|---|---|
| q0 | {q0} | {q1} | ∅ |
| q1 | {q1} | {q0, q1} | {q2} |
| q2 | ∅ | {q2} | ∅ |
Note: q1 goes to BOTH q0 and q1 on “1”. ε-closure of {q1} = {q1, q2}.
Step-by-step
Start: E({q0}) = {q0} (no ε-transitions from q0)
{q0} on 0: δ(q0, 0) = {q0}. E({q0}) = {q0}. → {q0}
{q0} on 1: δ(q0, 1) = {q1}. E({q1}) = {q1, q2} (q1 ⟶ε q2). → {q1, q2}
{q1, q2} on 0: δ(q1, 0) ∪ δ(q2, 0) = {q1} ∪ ∅ = {q1}. E({q1}) = {q1, q2}. → {q1, q2}
{q1, q2} on 1: δ(q1, 1) ∪ δ(q2, 1) = {q0, q1} ∪ {q2} = {q0, q1, q2}. E({q0, q1, q2}) = {q0, q1, q2}. → {q0, q1, q2} ← NEW STATE
{q0, q1, q2} on 0: δ(q0, 0) ∪ δ(q1, 0) ∪ δ(q2, 0) = {q0} ∪ {q1} ∪ ∅ = {q0, q1}. E({q0, q1}) = {q0, q1, q2}. → {q0, q1, q2}
{q0, q1, q2} on 1: δ(q0, 1) ∪ δ(q1, 1) ∪ δ(q2, 1) = {q1} ∪ {q0, q1} ∪ {q2} = {q0, q1, q2}. E = {q0, q1, q2}. → {q0, q1, q2}
Result
| DFA State | 0 | 1 | Accept? |
|---|---|---|---|
| {q0} | {q0} | {q1, q2} | No |
| {q1, q2} | {q1, q2} | {q0, q1, q2} | Yes (contains q2) |
| {q0, q1, q2} | {q0, q1, q2} | {q0, q1, q2} | Yes (contains q2) |
3 reachable DFA states. Accept states: {q1, q2} and {q0, q1, q2} (both contain q2, the NFA accept state).
NFA: states {q0, q1, q2}, Σ = {a, b}, q0 start, F = {q2}.
q0: ε → q1, a → q0. q1: b → q2. q2: a → q2.
Apply subset construction. How many DFA states are reachable?
Start: E({q0}) = {q0, q1} (q0 ⟶ε q1).
{q0, q1} on a: δ(q0, a) ∪ δ(q1, a) = {q0} ∪ ∅ = {q0}. E({q0}) = {q0, q1}.
{q0, q1} on b: δ(q0, b) ∪ δ(q1, b) = ∅ ∪ {q2} = {q2}. E({q2}) = {q2}. ✓
{q2} on a: {q2}. ✓ {q2} on b: ∅ = dead state.
∅ on a: ∅. ∅ on b: ∅. (Trap state.)
3 reachable DFA states: {q0, q1} (start), {q2} (accept), ∅ (trap).
~50% of exams, 3 pts. The exam defines a variant NFA model (modifying acceptance criteria) and asks: “Do [variant]s accept the same languages as NFAs?”
Standard NFA: accepts if ANY computation path ends in accept state RNFA: REJECTS if ANY computation path ends in non-accept state (equivalently: accepts only if ALL paths end in accept state) SNFA: accepts if EXACTLY ONE path ends in accept state MNFA: accepts if MAJORITY of paths end in accept state
RNFA = NFA in power (both recognize regular languages). - NFA: ∃ accepting path → accept - RNFA: ∃ rejecting path → reject (equivalently: ∀ paths accept → accept) - RNFA is “pessimistic” — one bad path kills acceptance - Key insight: RNFA acceptance = universal quantifier. NFA acceptance = existential. - But both recognize exactly the regular languages (proof via DFA conversion).
“Consider an RNFA which is a non-deterministic finite automaton like an NFA, except that it accepts and rejects strings differently. We say an RNFA rejects a word if there is at least one path of computation which, after reading the entire word, does not accept the word.
Do RNFAs accept the same languages as NFAs?”
Given NFA diagram: q0 (start), q1, q2 (accept). q0: 0→q0, 1→q1. q1: 0→q1, 0,ε→q2, 1→q1. q2: 1→q2.
“The word 1011 would be accepted if this was an NFA, but it is not accepted if this is an RNFA as there is a computation path that does not end in an accepting state.”
Yes, RNFAs accept exactly the regular languages. Prove both directions:
1. NFA → RNFA direction: Given NFA N, convert to DFA D (via subset construction). D is also an RNFA — since D is deterministic, there is exactly one computation path for each word, so “all paths accept” = “the one path accepts.” Therefore L(N) = L(D) = L(D as RNFA).
2. RNFA → NFA direction: Given RNFA R, convert to DFA D using subset construction, but with modified accept states: a subset state S ⊆ Q is accepting iff all q ∈ S are accept states in R. The resulting DFA D recognizes L(R). Since D is also an NFA, we have L(R) recognized by an NFA.
Key insight: A given machine accepts different words when interpreted as RNFA vs NFA (e.g., 1011 is accepted by the example NFA but rejected by the same machine as an RNFA). But the class of languages recognized is the same: regular languages. The DFA serves as the bridge — every DFA is both a valid NFA and a valid RNFA.
An SNFA accepts a word if EXACTLY ONE computation path ends in an accept state. Do SNFAs accept the same languages as NFAs?
Yes, SNFAs recognize exactly the regular languages.
Regular → SNFA: Given any regular language L, build a DFA D for L. Since D is deterministic, every word has exactly one computation path. Accepted words have exactly 1 accepting path; rejected words have 0. So D is a valid SNFA with L(D-as-SNFA) = L(D) = L.
SNFA → regular: Given SNFA S, we show L(S) is regular. The machine S is structurally an NFA. Let L≥1 = {w : at least one path accepts} (the standard NFA language) and L≥2 = {w : at least two paths accept}. Both are regular: L≥1 by standard NFA-to-DFA conversion, and L≥2 by a product construction that tracks two independent paths through S. Then L(S) = L≥1 \ L≥2, which is regular since regular languages are closed under set difference.
Exam shortcut (2-point answer): “Every DFA is an SNFA (one path per word). For the other direction, the SNFA language can be captured by a modified subset construction that tracks path counts, yielding a finite DFA. Therefore SNFAs recognize exactly the regular languages.”
An MNFA accepts a word if MORE THAN HALF of all computation paths end in an accept state. Do MNFAs accept the same languages as NFAs?
Yes, MNFAs recognize exactly the regular languages.
DFA → MNFA: Every DFA is already an MNFA. A DFA has exactly one computation path per word. If the word is accepted, 1/1 = 100% of paths accept (majority). If rejected, 0/1 = 0% (not majority). So L(DFA-as-MNFA) = L(DFA).
MNFA → DFA: Given MNFA M, use subset construction but track the fraction of paths in each state. The DFA state is a distribution over M’s states. Accept if >50% of the distribution weight is in M’s accept states. Since this distribution is determined by the state set (with multiplicities bounded by the subset construction), the result is a finite DFA.
The key insight is the same as RNFA/SNFA: the DFA is the bridge. Any DFA is trivially a valid MNFA (one path = majority), and the subset construction can be adapted to capture majority semantics.
1. Convert NFA to GNFA: - Add new start q_s (ε-transition to old start) - Add new accept q_a (ε from all old accept states) - Label all transitions with regex - Missing transitions = ∅ 2. Remove states one at a time (never q_s or q_a). When removing state q_rip, for every pair (qi, qj): R(qi, qj) = R_old(qi, qj) | R(qi, q_rip) . R(q_rip, q_rip)* . R(q_rip, qj) 3. When only q_s and q_a remain, the single edge label is the regex.
Convert NFA N (from subset construction example above) to regex via GNFA state elimination.
Step 1 — Build GNFA
States: qs, q0, q1, q2, qa.
Step 2 — Remove q2
q2 has self-loop 1, incoming from q1 (via ε), outgoing to qa (ε).
For pair (q1, qa):
R(q1, qa) = R_old(q1, qa) | R(q1, q2) · R(q2, q2)* · R(q2, qa)
= ∅ | ε · 1* · ε = 1*
Step 3 — Continue removing states
Remove q1, then q0, until only qs and qa remain. The final edge label is the regex for L(N).
The exam typically asks you to remove ONE specific state and draw the resulting GNFA. You don’t need to complete the full elimination — just apply the formula correctly for the specified state.
GNFA with states {qs, q0, q1, qa}. Edges: qs ⟶ε q0, q0 ⟶a q0, q0 ⟶b q1, q1 ⟶a q0, q1 ⟶b q1, q1 ⟶ε qa.
Remove q1. What are the new edge labels?
Removing q1. Self-loop on q1: b. Incoming to q1: q0 ⟶b q1. Outgoing from q1: q1 ⟶a q0, q1 ⟶ε qa.
R(q0, q0): a | b · b* · a = a | bb*a
R(q0, qa): ∅ | b · b* · ε = bb*
Resulting GNFA: qs ⟶ε q0, q0 ⟶(a|bb*a) q0, q0 ⟶bb* qa.
Full regex (removing q0 next): (a | bb*a)* bb* = (a | b+a)* b+.
Q3 often asks: “give a regex R with L(R) = [language].” No GNFA needed — just write the regex directly.
Strategy for complement-style languages (Σ* minus a finite set):
List what’s EXCLUDED, then build a regex that accepts everything else. Partition by first characters.
Give regex R with L(R) = Σ* − {aa, aaa}, Σ = {a, b}.
Analysis
We need all strings EXCEPT exactly “aa” and exactly “aaa”. Partition by what the string starts with:
Answer
R = ε | a | b(a|b)* | ab(a|b)* | aab(a|b)* | aaab(a|b)* | aaaa(a|b)*
Simplified: ε | a | (b | ab | aab | aaab | aaaa)(a|b)*
Exam question (Resit 24–25 Q3, 2 pts): “In our regular expressions we only allow concatenation, star, and union. Consider Extended Regular Expressions (ERE) which also allow intersection. Are EREs more powerful than REs?”
No. EREs have the same power as REs. Proof: Every ERE can be converted to an equivalent RE: 1. If the ERE has no intersections, it’s already an RE → convert to NFA (Thompson’s) 2. If the ERE is of the form x ∩ y: a. Recursively convert x and y to NFAs (or DFAs) b. Build the product DFA for intersection c. Convert back to RE (via GNFA state elimination) 3. Regular languages are closed under intersection, so any ERE describes a regular language → has an RE.
Are regular expressions with complement (allowing R̅ meaning Σ* \ L(R)) more powerful than standard REs?
No. Regular languages are closed under complement (flip accept/reject states of the DFA). So any RE-with-complement describes a regular language, which has a standard RE.
Proof: Given RE-with-complement expression E, convert to DFA (recursively handling complement by flipping accept states), then convert DFA back to RE via GNFA state elimination.
Find ONE word with TWO different leftmost derivations (or equivalently, two different parse trees).
Strategy: Look for a word where the grammar has a choice of which variable to expand first. Common sources:
5 steps in order:
Exam tip: the order matters. DEL before UNIT ensures you don’t reintroduce ε-rules when eliminating unit rules.
G: S → XX, X → aXb | ε.
Ambiguity proof
The word ab has two different leftmost derivations:
Derivation 1: S ⇒ XX ⇒ aXbX ⇒ aεbX ⇒ abε = ab
Derivation 2: S ⇒ XX ⇒ εX ⇒ X ⇒ aXb ⇒ aεb = ab
Two different leftmost derivations for “ab”. Grammar is ambiguous. □
CNF Conversion
START: S does not appear on any RHS → skip.
TERM: Replace terminals in aXb: S → XX, X → UaXUb | ε, Ua → a, Ub → b.
BIN: Break UaXUb into binary: X → UaT1 | ε, T1 → XUb.
So far: S → XX, X → UaT1 | ε, T1 → XUb, Ua → a, Ub → b.
DEL: X is nullable. For each rule containing X, add versions with X removed:
Remove X → ε. Result: S → XX | X | ε, X → UaT1, T1 → XUb | Ub, Ua → a, Ub → b.
S → ε is allowed in CNF (special case for start variable).
UNIT: S → X is a unit rule. Replace with X’s rules: S → UaT1.
Final: S → XX | UaT1 | ε, X → UaT1, T1 → XUb | Ub, Ua → a, Ub → b.
“Can we add a single rule to make L(G′) = L(G)*?”
Example from Resit 24–25 Q5b: G has S → XX, X → aXb | ε. Since ε ∈ L(G) (via S ⇒ XX ⇒ εε = ε), adding S → SS is sufficient. The rule S → SS allows concatenating any number of L(G) strings: S ⇒ SS ⇒ SSS ⇒ …, and the base case ε ∈ L(G) handles zero copies. So L(G′) = L(G)*.
General construction for L(G)*: Add a new start variable S′ with rules S′ → S′S′ | S | ε. This generates zero or more concatenations of L(G) strings. The new start avoids interference with existing rules.
G: S → AB | a, A → aA | ε, B → bB | b. Prove G is ambiguous.
This grammar is NOT ambiguous. (Trick question.)
L(G) = {a} ∪ {ambn | m ≥ 0, n ≥ 1}. From S → AB: A generates a* (zero or more a’s) and B generates b+ (one or more b’s). For any word ambn, the split between A and B is unique (A produces all a’s, B produces all b’s). S → a only produces “a”, which cannot come from S → AB (since B → bB | b cannot derive ε, any word from AB contains at least one b).
Every word in L(G) has exactly one leftmost derivation. Not ambiguous.
G: S → aSb | AB, A → aA | a, B → bB | ε. Convert to CNF.
START: S appears in aSb → Add S0 → S.
TERM: Replace terminals in mixed rules: S → UaSUb | AB, A → UaA | a, B → UbB | ε.
BIN: S → UaT1 | AB, T1 → SUb.
DEL: B is nullable. S → AB ⇒ add S → A. S0 → S (not nullable unless S is). Is S nullable? S → AB → Aε → A. A → aA | a ⇒ A not nullable. So S not nullable.
Remove B → ε. Add UbB with B removed: nothing new (Ub alone would be a terminal rule, already have Ub → b).
Result: S0 → S, S → UaT1 | AB | A, T1 → SUb, A → UaA | a, B → UbB, Ua → a, Ub → b.
UNIT: S0 → S: replace with S’s rules → S0 → UaT1 | AB | A. S → A: replace with A’s rules → S → UaT1 | AB | UaA | a. S0 → A: replace → S0 → UaT1 | AB | UaA | a.
Final CNF: S0 → UaT1 | AB | UaA | a / S → UaT1 | AB | UaA | a / T1 → SUb / A → UaA | a / B → UbB / Ua → a / Ub → b
Strategy:
Construct a CFG for L = {ambncn | m ≥ 1} ∪ {anbncm | m ≥ 1}.
Union: S → S1 | S2.
S1: ambncn with m ≥ 1. The a’s are independent, the b’s and c’s match.
S1 → A1 B1, A1 → aA1 | a, B1 → bB1c | ε.
S2: anbncm with m ≥ 1. The a’s and b’s match, the c’s are independent.
S2 → B2 C2, B2 → aB2b | ε, C2 → cC2 | c.
Key patterns:
G: S → XX, X → aXb | ε. Build PDA for L(G) with ≤ 6 states.
L(G) = {an1bn1an2bn2 | n1, n2 ≥ 0}
PDA Design
Idea: push a’s onto stack, pop on b’s. When stack empties after first block, can start second block.
States: qstart, qpush1, qpop1, qpush2, qpop2, qacc (6 states).
The key insight: the transition from block 1 to block 2 happens when the stack has only $ left (all a’s matched). The PDA can nondeterministically decide when to switch from pushing to popping in each block.
Construct a PDA for L = {anb2n | n ≥ 0} with ≤ 4 states.
Idea: push TWO stack symbols per a, pop one per b. Then n a’s push 2n symbols, and 2n b’s pop them all.
States: qstart, qpush, qpop, qacc.
Alternative: push one A per a, then for each b pop half an A (i.e., use nondeterminism). The double-push is cleaner.
Given a TM diagram, find words that cause specific behaviors (accept, reject, loop). Read configurations as (state, tape contents with head position).
Configuration notation: write the tape contents with the current state inserted before the symbol the head is reading.
Example: tape = “abcb”, head on second symbol, state q1 → configuration: a q1 bcb
Finding loops: look for ε (blank tape) or patterns that cause the head to bounce between states without making progress. Trace a few steps — if you see a repeated configuration, it loops.
Critical distinction:
L(M) being decidable does NOT mean M is a decider. A recognizer (that loops on some inputs) can still have a decidable language.
To show L(M) is decidable: identify what L(M) actually is (e.g., “all strings starting with a”), then argue that THIS language is decidable (build a different decider for it).
TM M with states {q0, q1, q2, qacc}, alphabet including a, b, c, and blank.
(a) Find a word w on which M loops
Answer: w = ε (blank tape).
Trace: q0 reads blank → writes c, goes to q1. q1 reads c → … (behavior creates a cycle that revisits the same configuration). After a few steps, the head bounces between states without ever reaching qacc or qreject.
Give 3 configurations showing the loop:
(b) Is L(M) decidable?
Analyze what M accepts. Determine the set L(M) explicitly. If L(M) turns out to be a regular or context-free language (or otherwise clearly decidable), the answer is YES — even though M itself is not a decider (it loops on some inputs).
Build a separate decider D for L(M) and argue D is correct.
“M loops on some inputs, therefore L(M) is undecidable” — WRONG. The existence of a loop in M says nothing about whether a DIFFERENT machine could decide L(M). The question is about the language, not the machine.
Construct (describe) a TM for L = {anbn | n ≥ 0} using ≤ 6 states. Describe the strategy and key transitions.
Strategy: repeatedly cross off one a and one b.
States: qstart (find a), qseekb (scan right for b), qreturn (scan left), qverify (check all matched), qacc, qrej.
TM M: states {q0, q1}, Σ = {a}, Γ = {a, ␣}. Transitions: q0 reads a → write a, move R, stay q0. q0 reads ␣ → write a, move L, go q1. q1 reads a → write a, move R, go q0.
(a) Find a word on which M loops and give 4 configurations. (b) What is L(M)?
(a) w = ε. Trace:
The TM keeps extending the tape with a’s and bouncing — infinite loop.
In fact, for ANY input w, M eventually hits a blank, writes a, bounces, and loops. M never accepts or rejects.
(b) L(M) = ∅. M never reaches an accept state on any input. The empty language is decidable (a decider that always rejects decides it).
Construct a DFA for L = {w ∈ {a, b}* | w has an odd number of a’s and even number of b’s}.
Track (a-parity, b-parity). 4 states: (even,even), (even,odd), (odd,even), (odd,odd).
Start: (even, even). Accept: (odd, even).
| State | a | b |
|---|---|---|
| (E, E) | (O, E) | (E, O) |
| (O, E) ✓ | (E, E) | (O, O) |
| (E, O) | (O, O) | (E, E) |
| (O, O) | (E, O) | (O, E) |
This is itself a product construction of “odd a’s” × “even b’s”.
NFA N: states {q0, q1, q2}, Σ = {a, b}, q0 start, F = {q2}.
q0 ⟶a {q0, q1}, q0 ⟶b {q0}. q1 ⟶a {q2}. q2 ⟶b {q2}.
Apply subset construction. Give the DFA transition table.
No ε-transitions. Start: {q0}.
{q0} on a: {q0, q1}. {q0} on b: {q0}.
{q0, q1} on a: δ(q0,a) ∪ δ(q1,a) = {q0,q1} ∪ {q2} = {q0,q1,q2}. On b: {q0} ∪ ∅ = {q0}.
{q0,q1,q2} on a: {q0,q1} ∪ {q2} ∪ ∅ = {q0,q1,q2}. On b: {q0} ∪ ∅ ∪ {q2} = {q0,q2}.
{q0,q2} on a: {q0,q1} ∪ ∅ = {q0,q1}. On b: {q0} ∪ {q2} = {q0,q2}.
| DFA State | a | b | Accept? |
|---|---|---|---|
| {q0} | {q0,q1} | {q0} | No |
| {q0,q1} | {q0,q1,q2} | {q0} | No |
| {q0,q1,q2} | {q0,q1,q2} | {q0,q2} | Yes |
| {q0,q2} | {q0,q1} | {q0,q2} | Yes |
4 reachable states. L(N) = “contains aa as a substring, possibly followed by anything” — more precisely: contains “aa” somewhere, and once matched, stays accepting on b’s.
Give a regex R for L = {w ∈ {a,b}* | w does NOT contain “aba” as a substring}.
Strategy: Build a DFA for “does not contain aba,” then read off the regex.
DFA states track progress toward the forbidden pattern:
Accept states: {s0, s1, s2}. Key constraint: after a block of a’s, the following b-block must have ≥2 b’s before any a can reappear (one b goes to s2, a second b returns to s0).
Valid strings: blocks of a+ separated by bb+ (at least 2 b’s), with optional leading/trailing b’s and a’s. Can end mid-pattern at s1 (trailing a’s) or s2 (trailing a+b).
R = b*(a+bb+)*(a+b?)?
Verify: “aba” requires a+bb+ between the a-blocks, but only one b — rejected ✓. “abba” = a+bb+ · a+ ✓. “bab” = b · a+b (ending at s2) ✓. “b” = b ✓. ε ✓.