CMPS 260 Spring 2024
HW #2 Sample Solutions

1. The problem was to minimize the following DFA:

δ
stateabInitial?Final?
054  
152   
220  
326  
441  
534   
623   

Solution: Recall that, for k≥0, Ik is the equivalence relation (on the states of the DFA) such that (p,q) ∈ Ik iff states p and q are "indistinguishable" with respect to all strings of length ≤ k. Which is to say that (p,q) ∈ Ik iff, for every string x ∈ Σ≤k, if δ*(p,x) = r (i.e., p ↝x r) and δ*(q,x) = s (i.e., q ↝x s), then states r and s are either both accepting or both non-accepting.

The algorithm whose execution was to be traced computes I0, then I1, then I2, then I3, etc., etc. (each one being a subset of its predecessor, meaning that zero or more equivalence classes of the predecessor get split up during each "round") until such time as Ik = Ik+1, at which point I has been computed (states p and q being related by I iff they are indistinguishable with respect to all strings of any length). The states of the minimized DFA correspond to the equivalence classes of I.

Now for the trace of execution:
I0 has two equivalence classes, one containing the non-accepting states and the other containing the accepting states. We start there and, in each round of the algorithm, we refine Ik to Ik+1.

Round 1
        [0]              [2]
  ---------------    -----------
   0   1   5   6      2   3   4
a [0] [0] [2] [2]    [2] [2] [2]
b [2] [2] [2] [2]    [0] [0] [0]

As a result of Round 1, we find that states 0 and 1 are 1-distinguishable from states 5 and 6. So the equivalence class {0,1,5,6} of I0 splits into two in going from I0 to I1. Thus, the equivalence classes of I1 are {0,1}, {5,6}, and {2,3,4}.

Round 2
    [0]        [5]          [2]
  -------    -------    -----------
   0   1      5   6      2   3   4
a [5] [5]    [2] [2]    [2] [2] [2]
b [2] [2]    [2] [2]    [0] [5] [0]

Round 2 tells us that equivalence class {2,3,4} in I1 splits into equivalence classes {2,4} and {3} in I2.

Round 3
    [0]        [5]        [2]       [3]
  -------    -------    -------   -------
   0   1      5   6      2   4       3
a [5] [5]    [3] [2]    [2] [2]      -
b [2] [2]    [2] [3]    [0] [0]      -

Round 3 tells us that states 5 and 6 are 3-distinguishable, so we split {5,6} into {5} and {6} and do yet another round.

Round 4
    [0]        [5]        [6]        [2]       [3]
  -------    -------    -------    -------    ------
   0   1        5          6        2   4       3
a [5] [5]       -          -       [2] [2]      -
b [2] [2]       -          -       [0] [0]      -

In Round 4, we find that no equivalence class splits in going from I3 to I4. Hence, I3 = I4 = I5 = ... = I and the DFA is minimized by merging states 0 and 1 into a single state and likewise states 2 and 4.

The result is the following (minimized) DFA:

δ
stateabInitial?Final?
{0,1} {5}{2,4}  
{2,4}{2,4}{0,1}  
{3} {2,4}{6}  
{5} {3}{2,4}   
{6} {2,4}{3}   


2. The problem was to apply the Cartesian Product Construction to the two DFAs shown below, M1 and M2, for the purpose of obtaining a DFA that accepts L(M1) ∩ L(M2).

M1
Stateδ
Start?Accepting? State IDab
q0q0q1
q1q2q0
q2q2q1

M2
Stateδ
Start?Accepting? State IDab
r0r1r1
r1r2r1
r2r1r0

Solution:

M
Stateδ
Start?Accepting? State IDab
[0,0][0,1][1,1]
[0,1][0,2][1,1]
[1,1][2,2][0,1]
[0,2][0,1][1,0]
[2,2][2,1][1,0]
[1,0][2,1][0,1]
[2,1][2,2][1,0]


3. As noted in the problem description, when the Cartesian Product construction is used to produce a DFA that accepts the intersection L1 ∩ L2 of the languages accepted by two given DFAs M1 and M2 (such as in the previous problem) having accepting sets of states F1 and F2, the set of accepting states in the resulting DFA is F = F1 × F2. Or, in other words, F = { [p,q] | p ∈ F1 ∧ q ∈ F2 }

(a) The only change necessary to make the resulting DFA accept the difference L1 − L2 between the two languages is to let F = F1 × (Q2 − F2) (where Q2 is the state set of M2). In other words, F = { [p,q] | p ∈ F1 ∧ q ∉ F2 }

(b) For symmetric difference, the accepting state set needs to be F = ((F1 × (Q2−F2) ∪ (Q1−F1) × F2). In other words, F = { [p,q] | (p ∈ F1 ∧ q ∉ F2) ∨ (p ∉ F1 ∧ q ∈ F2) }.

A more clever way to say the same thing is F = { [p,q]  |  (p ∈ F1) ≠ (q ∈ F2) }


4. Suppose that M = (Q, Σ, δ, q0, F) is a DFA that accepts language L. Then the language L' = { x ∈ L  |  for all y ∈ Σ+, xy ∉ L } is accepted by M' = (Q, Σ, δ, q0, F'), where

F' = { q ∈ F  |  all outgoing transitions from q go to dead states }

Note: By dead state here, we mean any state from which no accepting states are reachable. End of note.

In other words, the only change that needs to be made in going from M to M' is to make non-accepting any accepting state in M from which an accepting state can be reached via a sequence of one or more transitions.

The bonus question asks for a characteriztion of the accepting state(s) in M' under the asssumption that M is a minimal DFA.

Observe that, being minimal, M has at most one dead state. Also due to its being minimal, M has at most one accepting state all of whose outgoing transitions go to that dead state. If, indeed, M has such an accepting state, it is the lone accepting state in M' (according to the construction described above). It follows that, if M is minimal, then M' has at most one accepting state and that, if it exists, all its outgoing transitions go to the dead state.


5. Let #: {0,1}+ ⟶ ℕ be the standard mapping from binary numerals to nonnegative integers. The problem was to defise a DFA that accepts the language

{ x ∈ {0,1}+  |  #(x) % 4 = 1 }

Solution: The premise of the solution is that, after reading any prefix x of the given input string, the DFA should be in state r, where #(x) % 4 = r. As the only possible values for r are those in the range [0..4), there will be four states, named accordingly.

This premise makes sense only if the values of #(x0) % 4 and #(x1) % 4 can be predicted from the value of #(x) % 4. But, alas, they can.

Recall that, as pointed out in the instructions, #(x0) = 2·#(x) and #(x1) = 2·#(x) + 1.

Let m = #(x). Then m = 4k + r for some natural numbers k and r, where 0≤r<4. (Of course, r = m % 4.) We consider #(x0):

Case 0: r = 0. Then
  #(x0)

=   < prop. of #() >

  2 · #(x)

=   < m = #(x) >

  2 · m

=   < m = 4k >

  2 · (4k)

=   < algebra >

  4(2k) + 0
Case 1: r = 1. Then
  #(x0)

=   < prop. of #() >

  2 · #(x)

=   < m = #(x) >

  2 · m

=   < m = 4k + 1 >

  2 · (4k + 1)

=   < algebra >

  8k + 2

=   < algebra >

  4(2k) + 2
Case 2: r = 2. Then
  #(x0)

=   < prop. of #() >

  2 · #(x)

=    < m = #(x) >

  2 · m

=   < m = 4k + 2 >

  2 · (4k + 2)

=   < algebra >

  8k + 4 

=   < algebra >

  4(2k + 1)
Case 3: r = 3. Then
  #(x0)

=   < prop. of #() >

  2 · #(x)

=    < m = #(x) >

  2 · m

=   < m = 4k + 3 >

  2 · (4k + 3)

=   < algebra >

  8k + 6 

=   < algebra >

  4(2k + 1) + 2

For example, Case 3 tells us that if #(x) % 4 = 3, then #(x0) % 4 = 2 (because #(x0) exceeds a multiple of two by two).

A similar analysis can be carried out upon #(x1). The results are summarized in the following table, which practically describes the δ function of our DFA.

#(x) % 4 #(x0) % 4 #(x1) % 4
001
123
201
323

Here is the DFA, both in state transition form and table form.

Stateδ
Start?Accepting? State ID01
001
123
201
323

Ah, but states 0 and 2 are indistinguishable and thus can be merged into a single state.

A question that could arise is why it is justified for state 0 to be the initial state. After all, state 0 is the one that should be reached upon the machine reading a bit string whose numerical equivalent (according to #()) is a multiple of four. The empty string does not qualify. Or does it? Well, it does if we define #(λ) = 0. No harm comes from doing that in this context. Now, if the language were to contain bit strings that #() maps to zero, but only non-empty such strings, then we would have to make state 0 accepting and have a new initial state that was non-accepting and had the same outgoing transitions as state 0.