Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
lfa:lab02-dfa [2020/10/19 11:20]
dmihai [2. Implementing DFAs]
lfa:lab02-dfa [2021/10/13 16:13] (current)
ioana.georgescu [Classes in Python]
Line 1: Line 1:
-====== Deterministic finite automata ======+====== ​2. Deterministic finite automata ======
  
-==== 1. Writing DFAs ==== +===== Classes in Python ​=====
-1.1. Write a DFA which accepts the language $ L=\{w \in \{0,1\}^* \text{ | w contains an odd number of 1s} \} $ +
-Hint: +
-  * in a DFA, delta is total!+
  
-1.2 Define ​DFA which accepts arithmetic expressionsConsider ​the following ​definition ​for arithmetic expressions:​+Python supports ​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).
  
-<​code>​ +Below, we illustrate some examples of Python'​s object-oriented idiom: 
-<​expr> ​::= <var> | <​expr>​ + <​expr>​ | <​expr>​ * <​expr>​ + 
-<​var> ​::= STRING+<​code ​python
 +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)
 </​code>​ </​code>​
  
-Hint+===== 2.1. The class Dfa (Python) ===== 
-  * how would you define ​the alphabet ​for the DFA? + 
-  * can <​expr>​ be the empty string?+**2.1.1.** Define the class ''​Dfa''​ which encodes deterministic finite automata. It must store
 +  * the alphabet 
 +  * the delta function 
 +  * the initial state 
 +  * the set of final states 
 + 
 +**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:
  
-==== 2. Implementing DFAs ==== 
-Consider the following encoding of a DFA: 
 <​code>​ <​code>​
-   <number_of_states+<initial_state
-   ​<list_of_final_states> +<state> <char> <​state>​ 
-   <​state>​ <symbol> <state>+... 
 +... 
 +<final_state_1> <final_state_2>​ ... <​final_state_n>
 </​code>​ </​code>​
 +
 +where:
 +  * the initial state is given on the first line of the input
 +  * each of the subsequent lines encode transitions (states are integers)
 +  * the last line encodes the set of final states.
  
 Example: Example:
 <​code>​ <​code>​
-+0
-2 3+
 0 a 1 0 a 1
 1 b 2 1 b 2
 2 a 0 2 a 0
 +1 2
 </​code>​ </​code>​
  
-2.1. Write a function which takes a DFA encoding as above and returns ​a DFA representation. Define a class "​DFA"​.+**2.1.3.** Implement ​member ​function which takes a **configuration** (pair of state and rest of word) and returns ​the next configuration.
  
-2.2Add method accept ​which takes a word and returns true if it is accepted by the DFA+**2.1.4.** Implement ​member function ​which verifies if a word is **accepted** by a Dfa.
  
-2.3. Add a method step with takes a DFA configuration and returns the "​next-step"​ configuration of the DFAHow is a configuration defined?+===== 2.2The Dfa Algebraic Datatype (Haskell) =====
  
-2.4(*) Write a method which: +During the lecture, Dfa states were encoded as integersAs we will soon seewe will need to provision our implementationso that other types may encode states
-  * takes a list of DFAs $ a_1a_2, ..., a_n$ +  * Should ​the ADT ''​DFA''​ be **monomorphic** or **polymorphic**?​
-  * takes a string $ s$. We know the string consists of a sequence of words, each accepted by some dfa in the list. +
-  ​returns a list of pairs $ (w_1,a_1), ...(w_i,​a_i) ... (w_n,a_n)$ such that $ w_1w_2... w_n = s$ and the dfa $ a_i$ accepts word $ w_i$, for each i from 1 to n.+
  
-Example:+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: 
 +  * new constraints 
 +  * **operations** which are specific to states only. 
 + 
 +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: 
 +<code haskell>​ 
 +{- 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 
 +</​code>​ 
 + 
 +<​blockquote>​** 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) 
 +</​blockquote>​ 
 +**2.2.1.** Implement the datatype ''​DFA''​. It must store: 
 +  * the alphabet 
 +  * the delta function 
 +  * the initial state 
 +  * the set of final states 
 + 
 + 
 +---- 
 + 
 +**2.2.2.** Define a function which takes a string of the following form showed below, and returns a DFA **with states as integers**:
 <​code>​ <​code>​
-l = [a1, a2, a3] +<​initial_state>​ 
- ''' ​ +<​state>​ <​char>​ <​state>​ 
-    a1 accepts sequences of digits [0-9] +... 
-    a2 accepts sequences of lowercase symbols [a-z] +... 
-    a3 accepts operands (+ and *) +<​final_state_1>​ <​final_state_2>​ ... <​final_state_n>​ 
- '''​ +</​code>​
-s = "​var+40*2300"​+
  
-our function returns+where
-[("​var",​2), ("​+",​3),​ ("​40",​1),​ ("*",3), ("​2300",​1)]+  * the initial state is given on the first line of the input 
 +  * each of the subsequent lines encode transitions ​(states are integers) 
 +  ​the last line encodes the set of final states. 
 + 
 +Example: 
 +<​code>​ 
 +
 +0 a 1 
 +1 b 2 
 +2 a 0 
 +1 2
 </​code>​ </​code>​
 +
 +**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:
 +
 +  * **2.3.1.** $ L=\{w \in \{0,1\}^* \text{ | w contains an odd number of 1s} \} $
 +  * **2.3.2.** The language of binary words which contain **exactly** two ones
 +  * **2.3.3.** The language of binary words which encode odd numbers (the last digit is least significative)
 +  * **2.3.4.** (hard) The language of words which encode numbers divisible by 3.
 +
 +
 +
 +
 +
 +
 +