I'm writing a DFA minimizer using Hopcroft's algorithm. While testing some regular expressions, I came out with an issue in the algorithm's output relative to two particular regular expressions:
- a(b|c)*
- a(b|c*)
P.S.: the assumption is that both regular expressions are valid, but if that's not the case please let me know, I wouldn't be able to see what's wrong.
The difference between the two is that the first one allows for the letters b and c to be consumed an indefinite number of times, while the second one only allows for the letter c to be repeated indefinitely. This makes the scanner reach an accepting state if, after reading the letter a, it reads b. That is, it should stop when reading ab and consider an input like abbbb wrong, but acccc correct.
Let's generate the DFA for the first regex. Accepting states are in green. The picture below shows the DFA and its minimization.
All is good, let's generate the DFA for the second regex now.
After applying Hopcroft's algorithm, it occurs to me that the result is the same. However, the minimization of the second DFA is incorrect because it also allows to repeat the letter b indefinitely. Did I apply the algorithm in an incorrect way, is this a side effect of that particular regular expression? I can't seem to figure out.
I followed the pseudocode found on Engineering a Compiler, 2nd edition as explained in pages 54 to 57. The graphs are generated first using Thompson's construction, then the subset construction to get a DFA and minimized using Hopcroft's algorithm.