Table of Contents

2. Deterministic finite automata

Classes in Python

Python supports a limited version of Object-Oriented programming, which includes class definitions and inheritance. The concept of interface and interface implementation is absent. Hence, when inheriting a function, it is the job of the programmer to make sure a method is overloaded correctly (otherwise it is just another definition of the class).

Below, we illustrate some examples of Python's object-oriented idiom:

class Example:
   # the class constructor.
   def __init__(self,param1,param2):
      # the keyword self is similar to this from Java
      # it is the only legal mode of initialising and referring class member variables
      self.member1 = param1  
      # here member2 is a local variable, which is not visible outside of the constructor
      member2 = param2
 
   def fun(self):
      # a member function must always refer self as shown here. Otherwise it is just a function
      # defined in the scope of the class, not a member function.
      return 0
 
   def plus(self,x,y):
      return x + y
 
   # this is the equivalent of Java's toString method
   def __str__(self):
      string = ...
      return string
 
#global scope
 
#class instantiation
e = Example(1,2) 
 
#method calls:
e.fun()
 
print(e)

2.1. The class Dfa (Python)

2.1.1. Define the class Dfa which encodes deterministic finite automata. It must store:

Optional: you may consider defining a class State to encode more general Dfas where states are not confined to integers. This will be useful later in your project. However, you will need to define a hash-function in order to use dictionaries over states. More details, google hashing in Python.

2.1.2. Define a constructor for Dfas, which takes a multi-line string of the following form:

<initial_state>
<state> <char> <state>
...
...
<final_state_1> <final_state_2> ... <final_state_n>

where:

Example:

0
0 a 1
1 b 2
2 a 0
1 2

2.1.3. Implement a member function which takes a configuration (pair of state and rest of word) and returns the next configuration.

2.1.4. Implement a member function which verifies if a word is accepted by a Dfa.

2.2. The Dfa Algebraic Datatype (Haskell)

During the lecture, Dfa states were encoded as integers. As we will soon see, we will need to provision our implementation, so that other types may encode states.

Also, we shall require a few constraints on what a proper state type should be. States should be: (i) comparable via equality, (ii) support an ordering. Later on we may add:

How can we group all these constraints and support for future state operations?

Finally, in order to encode transitions and sets, we need the Map and Set datatypes which are available in their own modules:

{- We do import the data constructor Map and the infix function (!) as unqualified, to make them easier to use (Map.Map and Map.(!) is not very legible) -}
import Data.Map (Map, (!))
{-
the keyword qualified forces us to prefix each function call from the module Data.Map with "Map." this is useful for two reasons:
   - some function names overlap
   - it makes the code more legible, by making the programmer aware of the module location of the called function
-}
import qualified Data.Map as Map
 
import Data.Set (Set)
import qualified Data.Set as Set

How to choose between lists and sets during the implementation?

  • Do you need to make sure elements are unique? (go for sets)
  • Do you need to iterate a lot over elements, and the collection size is not really big (go for lists)

2.2.1. Implement the datatype DFA. It must store:


2.2.2. Define a function which takes a string of the following form showed below, and returns a DFA with states as integers:

<initial_state>
<state> <char> <state>
...
...
<final_state_1> <final_state_2> ... <final_state_n>

where:

Example:

0
0 a 1
1 b 2
2 a 0
1 2

Hint: Use splitBy from PP.


2.2.3. Enroll the DFA type in class Show.

2.2.4. Implement function which takes a DFA and a configuration (pair of state and rest of word) and returns the next configuration.

2.2.5. Implement a function which verifies if a word is accepted by a Dfa. What kind of general list-operation best matches the accepting process?

2.3. Dfa practice

Write Dfas and test them using your implementation, for the following languages: