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:2024:lab04 [2024/10/27 23:14]
cata_chiru
lfa:2024:lab04 [2024/10/29 09:27] (current)
cata_chiru
Line 62: Line 62:
     crt_lst = list(set(lst))     crt_lst = list(set(lst))
     return sorted(crt_lst,​ key = lambda x: (len(x), x))     return sorted(crt_lst,​ key = lambda x: (len(x), x))
 + 
 # Global variable used to threshold the number of Star items # Global variable used to threshold the number of Star items
 INNER_STAR_NO_ITEMS = 3 INNER_STAR_NO_ITEMS = 3
 + 
 class Regex: class Regex:
     '''​Base class for Regex ADT'''​     '''​Base class for Regex ADT'''​
 + 
     def __str__(self) -> str:     def __str__(self) -> str:
         '''​Returns the string representation of the regular expression'''​         '''​Returns the string representation of the regular expression'''​
         pass         pass
 + 
     def gen(self) -> [str]:     def gen(self) -> [str]:
         '''​Return a representative set of strings that the regular expression can generate'''​         '''​Return a representative set of strings that the regular expression can generate'''​
         pass         pass
 + 
 +    def __len__(self) -> str:
 +        '''​Returns the length of the regular expression'''​
 +        pass 
  
     def eval_gen(self):​     def eval_gen(self):​
         '''​Prints the set of strings that the regular expression can generate'''​         '''​Prints the set of strings that the regular expression can generate'''​
         pass         pass
 + 
 # TODO 0: Implementati Clasa Void dupa blueprint-ul de mai sus # TODO 0: Implementati Clasa Void dupa blueprint-ul de mai sus
 class Void(Regex):​ class Void(Regex):​
     '''​Represents the empty regular expression'''​     '''​Represents the empty regular expression'''​
 + 
     # Va returna Void ca string     # Va returna Void ca string
     def __str__(self) -> str:     def __str__(self) -> str:
         pass         pass
 + 
     # Va genera un obiect din Python corespunzatoar clasei void     # Va genera un obiect din Python corespunzatoar clasei void
     def gen(self) -> [str]:     def gen(self) -> [str]:
         pass         pass
-    ​+      
 +    def __len__(self):​ 
 +        return 0 
     def eval_gen(self):​     def eval_gen(self):​
         print("​Void generates nothing"​)         print("​Void generates nothing"​)
- +  
 + 
 # TODO 1: Implementati Clasa Epsilon-String (Empty) dupa blueprint-ul de mai sus # TODO 1: Implementati Clasa Epsilon-String (Empty) dupa blueprint-ul de mai sus
 class Empty(Regex):​ class Empty(Regex):​
     '''​Represents the empty string regular expression'''​     '''​Represents the empty string regular expression'''​
 + 
     # Va returna Empty ca string     # Va returna Empty ca string
     def __str__(self) -> str:     def __str__(self) -> str:
         pass         pass
 + 
     # Va returna o lista corespunzatoare a ce stringuri produce sirul vid     # Va returna o lista corespunzatoare a ce stringuri produce sirul vid
     def gen(self) -> [str]:     def gen(self) -> [str]:
         pass         pass
-    ​+ 
 +    # Va returna lungimea corespunzatoare sirului vid 
 +    def __len__(self) -> int: 
 +        pass 
 + 
     def eval_gen(self):​     def eval_gen(self):​
-        print("​Empty string generates ''​."​) +        print(f"Empty string ​has length {len(self)} ​generates ''​."​) 
 + 
 # TODO 2: Implementati functionalitatile necesare pentru Clasa Symbol dupa blueprint-ul de mai sus # TODO 2: Implementati functionalitatile necesare pentru Clasa Symbol dupa blueprint-ul de mai sus
 class Symbol(Regex):​ class Symbol(Regex):​
     '''​Represents a symbol in the regular expression'''​     '''​Represents a symbol in the regular expression'''​
 + 
     def __init__(self,​ char: str):     def __init__(self,​ char: str):
         self.char = char         self.char = char
 + 
     # TODO 2: Completati metodele __str__ si gen pentru clasa Symbol ​   ​     # TODO 2: Completati metodele __str__ si gen pentru clasa Symbol ​   ​
     def __str__(self) -> str:     def __str__(self) -> str:
         pass         pass
 + 
     def gen(self) -> [str]:     def gen(self) -> [str]:
         pass         pass
-    ​+ 
 +    def __len__(self) -> int: 
 +        return 1 
     def eval_gen(self):​     def eval_gen(self):​
         self.gen()         self.gen()
 + 
  # Dorim sa pastram in atributul words al clasei curente stringurile generate cu gen(self)  # Dorim sa pastram in atributul words al clasei curente stringurile generate cu gen(self)
-        return "​Symbol {self.char} generates {self.words}"​ +        return ​f"​Symbol {self.char} has length {len(self)} generates {self.words}"​ 
 + 
 # TODO 3: Implementati functionalitatile necesare pentru Clasa Union dupa blueprint-ul de mai sus # TODO 3: Implementati functionalitatile necesare pentru Clasa Union dupa blueprint-ul de mai sus
 class Union(Regex):​ class Union(Regex):​
Line 137: Line 151:
     def __init__(self,​ *arg: [Regex]):     def __init__(self,​ *arg: [Regex]):
         self.components = arg         self.components = arg
 + 
 +    # TODO 3: Completati metodele __str__, gen, __len__ si eval_gen pentru clasa Union
  
-    # TODO 3Completati metodele __str__, gen si eval_gen pentru clasa Union    ​+    # HintLook at the str.join method to create (expr1|expr2|...)
     def __str__(self) -> str:     def __str__(self) -> str:
         pass         pass
 + 
     def gen(self) -> [str]:     def gen(self) -> [str]:
- pass +        ​pass 
-    ​+ 
 +    ​# We will consider the len of a Union as the max length of its components 
 +    def __len__(self) -> int: 
 +        pass 
     # Dupa modelul de la Symbol, vom dori ca urmatoarele eval sa implementeze     # Dupa modelul de la Symbol, vom dori ca urmatoarele eval sa implementeze
-    # return "Class {varianta toString() a clasei) generates {self.words}"​+    # return "Class {varianta toString() a clasei) ​has length {len(self)} and generates {self.words}"​
     def eval_gen(self) -> str:     def eval_gen(self) -> str:
- pass +     ​pass 
 + 
 # TODO 4: Implementati functionalitatile necesare pentru Clasa Concat dupa blueprint-ul de mai sus # TODO 4: Implementati functionalitatile necesare pentru Clasa Concat dupa blueprint-ul de mai sus
 class Concat(Regex):​ class Concat(Regex):​
     '''​Represents the concatenation of two regular expressions'''​     '''​Represents the concatenation of two regular expressions'''​
 + 
     def __init__(self,​ *arg : [Regex]):     def __init__(self,​ *arg : [Regex]):
         self.components = arg         self.components = arg
- +  
-    # TODO 4: Completati metodele __str__, gen si eval_gen pentru clasa Concat+    # TODO 4: Completati metodele __str__, gen, __len__ ​si eval_gen pentru clasa Concat
     def __str__(self) -> str:     def __str__(self) -> str:
 +        pass
 + 
 +    def gen(self) -> [str]:
         pass         pass
  
-    def gen(self) -> [str]: +    def __len__(self) -> int
- pass +        pass
-            +
-    def eval_gen(self) -> str+
- pass+
  
 +    def eval_gen(self) -> str:
 +     pass
 + 
 # TODO 5: Implementati functionalitatile necesare pentru Clasa Star dupa blueprint-ul de mai sus # TODO 5: Implementati functionalitatile necesare pentru Clasa Star dupa blueprint-ul de mai sus
 class Star(Regex):​ class Star(Regex):​
Line 172: Line 195:
     def __init__(self,​ regex: Regex):     def __init__(self,​ regex: Regex):
         self.regex = regex         self.regex = regex
 +
 +        # To memorize the base words generated by the regex inside the star, we store them in a list
         self.base_words = [""​]         self.base_words = [""​]
-        self.base_gen() 
         self.words = []         self.words = []
 + 
 +    # TODO 5: Completati metodele __str__, gen, __len__, eval_gen pentru clasa Star
 +    def __str__(self) -> str:
 +        pass
 + 
 +    def gen(self, no_items = 10) -> [str]:
 +        pass
  
- +    ​To ease your implementation we will consider a big number e.g. 1000000 as Infinity 
-    ​TODO 5: Completati metodele __str__, gen, eval_gen pentru clasa Star +    def __len__(self) ​-> int:
-    def __str__(self):+
         pass         pass
- +  
-    def base_gen(self): +    def eval_gen(self, ​no_items = 10):
-        '''​To memorize the base words generated by the regex inside the starwe store them in a list'''​ +
-        if type(self.regex== Star: +
-     # Implement Star.gen with a limiting threshold+
      pass      pass
-         +  
- # Implement Regex.gen for the rest + 
- pass             +
- +
- +
-    def gen(self, no_items = 10): +
- pass +
- +
-    def eval_gen(self,​ no_items = 10): +
- pass +
- +
 if __name__ == "​__main__":​ if __name__ == "​__main__":​
- 
-    # Example usage 
- 
     r1 = Symbol('​a'​)     r1 = Symbol('​a'​)
     r2 = Symbol('​b'​)     r2 = Symbol('​b'​)
     regex_union = Union(r1, r2)     regex_union = Union(r1, r2)
     regex_union.eval_gen()     regex_union.eval_gen()
 + 
     e2 = Union(Symbol('​a'​),​Symbol('​b'​),​ Symbol('​c'​))     e2 = Union(Symbol('​a'​),​Symbol('​b'​),​ Symbol('​c'​))
     e4 = Concat(r1, e2)     e4 = Concat(r1, e2)
     e4.eval_gen()     e4.eval_gen()
-    ​+ 
     e5 = Concat(e2, e2, r2)     e5 = Concat(e2, e2, r2)
     e5.eval_gen()     e5.eval_gen()
 + 
     star_ex = Star(r1)     star_ex = Star(r1)
     star_ex.eval_gen()     star_ex.eval_gen()
 + 
     regex_concat = Concat(regex_union,​ star_ex)     regex_concat = Concat(regex_union,​ star_ex)
     regex_concat.eval_gen()     regex_concat.eval_gen()
 + 
     last_expr = Concat(Star(Union(Symbol('​a'​),​ Symbol('​b'​))),​ Symbol('​b'​),​ Star(Symbol('​c'​)))     last_expr = Concat(Star(Union(Symbol('​a'​),​ Symbol('​b'​))),​ Symbol('​b'​),​ Star(Symbol('​c'​)))
     last_expr.eval_gen()     last_expr.eval_gen()
-    ​</​code>​+</​code>​
     ​     ​
 The output should be similar to: The output should be similar to:
 <​code>​ <​code>​
-Union (a | b) generates ['​a',​ '​b'​].+Union (a | b) has length 1 and generates ['​a',​ '​b'​].
  
-Concat (a(a | b | c)) generates ['​aa',​ '​ab',​ '​ac'​].+Concat (a(a | b | c)) has length 2 and generates ['​aa',​ '​ab',​ '​ac'​].
  
-Concat ((a | b | c)(a | b | c)b) generates ['​aab',​ '​abb',​ '​acb',​ '​bab',​ '​bbb',​ '​bcb',​ '​cab',​ '​cbb',​ '​ccb'​].+Concat ((a | b | c)(a | b | c)b) has length 3 and generates ['​aab',​ '​abb',​ '​acb',​ '​bab',​ '​bbb',​ '​bcb',​ '​cab',​ '​cbb',​ '​ccb'​].
  
-Star (a*) generates ['',​ '​a',​ '​aa',​ '​aaa',​ '​aaaa',​ '​aaaaa',​ '​aaaaaa',​ '​aaaaaaa',​ '​aaaaaaaa',​ '​aaaaaaaaa',​ '​aaaaaaaaaa',​ '​...'​].+Star (a*) has length 10000000 ​generates ['',​ '​a',​ '​aa',​ '​aaa',​ '​aaaa',​ '​aaaaa',​ '​aaaaaa',​ '​aaaaaaa',​ '​aaaaaaaa',​ '​aaaaaaaaa',​ '​aaaaaaaaaa',​ '​...'​].
  
-Concat ((a | b)(a*)) generates ['​a',​ '​b',​ '​aa',​ '​ba',​ '​aaa',​ '​baa',​ '​aaaa',​ '​baaa'​].+Concat ((a | b)(a*)) ​has length 10000001 and generates ['​a',​ '​b',​ '​aa',​ '​ba',​ '​aaa',​ '​baa',​ '​aaaa',​ 'baaa', '...'].
  
-Concat (((a | b)*)b(c*)) generates ['​b',​ '​ab',​ '​bb',​ '​bc',​ '​aab',​ '​abb',​ '​abc',​ '​bab',​ '​bbb',​ '​bbc',​ '​bcc',​ '​aaab',​ '​aabb',​ '​aabc',​ '​abab',​ '​abbb',​ '​abbc',​ '​abcc',​ '​baab',​ '​babb',​ '​babc',​ '​bbab',​ '​bbbb',​ '​bbbc',​ '​bbcc',​ 'bccc', '​aaaab',​ 'aaabb', '​...'​].+Concat (((a | b)*)b(c*)) ​has length 20000001 and generates ['​b',​ '​ab',​ '​bb',​ '​bc',​ '​aab',​ '​abb',​ '​abc',​ '​bab',​ '​bbb',​ '​bbc',​ '​bcc',​ '​aaab',​ '​aabb',​ '​aabc',​ '​abab',​ '​abbb',​ '​abbc',​ '​abcc',​ '​baab',​ '​babb',​ '​babc',​ '​bbab',​ '​bbbb',​ '​bbbc',​ '​bbcc',​ '​bccc',​ '​...'​].
  
 </​code>​ </​code>​
Line 246: Line 260:
 For example, what is the outer class of a(a|b|c)? For example, what is the outer class of a(a|b|c)?
  
-/*<​hidden> ​+<​hidden ​Answer
 Concat Concat
-</​hidden>​*/+</​hidden>​
  
 How can we write this Regex using our classes? How can we write this Regex using our classes?
  
-/*<​hidden> ​+<​hidden ​Answer
 Concat(Symbol('​a'​),​ Union(Symbol('​a'​),​ Symbol('​b'​),​ Symbol('​c'​)) Concat(Symbol('​a'​),​ Union(Symbol('​a'​),​ Symbol('​b'​),​ Symbol('​c'​))
-</​hidden>​*/+</​hidden>​
  
  
 <​note>​ <​note>​
- 
 Note that we have used the following code structures that takes a variable number of parameters as inputs for Concat and Union constructors:​ Note that we have used the following code structures that takes a variable number of parameters as inputs for Concat and Union constructors:​
  
-<​code>​+<​code ​python>
     def __init__(self,​ *arg : [Regex]):     def __init__(self,​ *arg : [Regex]):
         self.components = arg         self.components = arg
- 
 </​code>​ </​code>​
  
 This design choice was meant to ease your work when representing more complex regexes. The alternative would be to use binary operations and fuse the ones identical together: (a|b|c) = Concat(Symbol('​a'​),​ Concat(Symbol('​b'​),​ Symbol('​c'​)) = (a|(b|c)) This design choice was meant to ease your work when representing more complex regexes. The alternative would be to use binary operations and fuse the ones identical together: (a|b|c) = Concat(Symbol('​a'​),​ Concat(Symbol('​b'​),​ Symbol('​c'​)) = (a|(b|c))
- 
 </​note>​ </​note>​
  
 What should it generate? What should it generate?
- +<​hidden ​Answer
-/*<​hidden> ​+
 [aa, ab, ac] [aa, ab, ac]
-</​hidden>​*/+</​hidden>​
  
 Therefore, we should analyse each possibility and think for each class if having other types of regular expressions inside affects the way in which the regex generates further and adapt our code to suit those class-recursions. Therefore, we should analyse each possibility and think for each class if having other types of regular expressions inside affects the way in which the regex generates further and adapt our code to suit those class-recursions.
  
 We should develop this process from simple examples to more complex ones: Symbol, Concat(Symbol,​ Symbol), Union(Symbol,​ Symbol), Concat(Symbol,​ Union), Concat(Union,​ Union)... We should develop this process from simple examples to more complex ones: Symbol, Concat(Symbol,​ Symbol), Union(Symbol,​ Symbol), Concat(Symbol,​ Union), Concat(Union,​ Union)...
- 
  
 <​note>​ <​note>​