def remplacer_etat(self, ancien, nouveau): if isinstance(ancien, Etat) and isinstance(nouveau, Etat): if ancien in self.__etats: self.ajouter_etats(nouveau) nouvelle_transition = list() for transtion in self.transitions: if transtion.depart == ancien: nouvelle_transition.append( Transition(nouveau, transtion.symbole, transtion.arrive)) if transtion.arrive == ancien: nouvelle_transition.append( Transition(transtion.depart, transtion.symbole, nouveau)) for transtion in nouvelle_transition: self.ajoute_transition(transtion) if self.etat_initial == ancien: self.ajouter_initital(nouveau) if ancien in self.etats_finaux: self.ajouter_final(nouveau) self.supprime_etat(ancien) self.automate_modifier.emit() else: raise ValueError("valeur non presente") else: raise TypeError("type non prit en charge")
def faire_union(automate1: Automate, automate2: Automate): if not isinstance(automate1, Automate) or not isinstance( automate2, Automate): raise TypeError("L'addition se fais uniquement entre les automate") initial = GenerateurAutomate.etat_initial() final = GenerateurAutomate.etat_final() ancien_initial = [automate1.etat_initial, automate2.etat_initial] ancien_finaux = [*automate1.etats_finaux, *automate2.etats_finaux] nouveaux_etats = [*automate1.etats, *automate2.etats, initial, final] nouvelle_transition = [*automate1.transitions, *automate2.transitions] nouvel_alphabet = Alphabet( [*automate1.alphabet.list, *automate2.alphabet.list]) automate = Automate(nouvel_alphabet, nouveaux_etats, initial, [final], nouvelle_transition) for etat in ancien_initial: transition_initial = Transition(initial, '', etat) automate.ajoute_transition(transition_initial) for etat in ancien_finaux: transition_final = Transition(etat, '', final) automate.ajoute_transition(transition_final) return automate
def faire_kleen(automate): if not isinstance(automate, Automate): raise TypeError('Kleen est possible uniquement sur un automate') initial = GenerateurAutomate.etat_initial() final = GenerateurAutomate.etat_final() ancien_initial = automate.etat_initial ancien_finaux = automate.etats_finaux.copy() print(initial) automate.ajouter_etats(initial) automate.ajouter_etats(final) automate.ajouter_initital(initial) for etat in ancien_finaux: automate.retirer_final(etat) automate.ajouter_final(final) transition_initial = Transition(initial, '', ancien_initial) automate.ajoute_transition(transition_initial) for etat in ancien_finaux: transition_final = Transition(etat, '', final) automate.ajoute_transition(transition_final) transition_boucle = Transition(etat, '', ancien_initial) automate.ajoute_transition(transition_boucle) transition_kleen = Transition(initial, '', final) automate.ajoute_transition(transition_kleen) return automate
def union_automate(self, automate): automate_1 = self.completer() if isinstance(automate, Automate): automate_2 = Automate.a_partir_de(automate) for etat in automate_2.etats: if etat in self.etats: automate_2.remplacer_etat(etat, Automate.genere_etat()) automate_2 = automate.completer() new_alphabet = set() for i in automate_1.alphabet.list: new_alphabet.add(i) for i in automate_2.alphabet.list: new_alphabet.add(i) for etat in automate_1.etats_finaux: if not etat.nom: etat.definir_nom(automate_1.nom) for etat in automate_2.etats_finaux: if not etat.nom: etat.definir_nom(automate_2.nom) new_alphabet = Alphabet(new_alphabet) new_transition = automate_1.transitions.union( automate_2.transitions) new_etat = automate_1.etats.union(automate_2.etats) new_etat.add(Etat('start')) print( f"Etat automate {automate_1.etat_initial} {automate_2.etat_initial}" ) new_transition.add( Transition(Etat('start'), '', automate_1.etat_initial)) new_transition.add( Transition(Etat('start'), '', automate_2.etat_initial)) new_finaux = automate_1.etats_finaux.union(automate_2.etats_finaux) resultat = Automate(new_alphabet, new_etat, Etat('start'), new_finaux, new_transition).determiniser().minimiser() resultat.parents = [ *automate_1.parents, *automate_2.parents, automate_1, automate_2 ] resultat.nom = self.nom return resultat
def convertir_en_nfa(self): if self.type != Type.eAFN: raise TypeError( f'Conversion autorisee uniquement pour les {Type.eAFN} ') etat_initial = self.etat_initial etat_finaux = list() transition = list() fermeture_epsilon = {} for etat in self.etats: fermeture_epsilon[etat] = self.epsilon_fermeture(etat) for etat in self.etats: if self.etats_finaux.intersection(set(fermeture_epsilon[etat])): etat_finaux.append(etat) for symbole in self.alphabet.list: etats_destination = list() for etat_epsilon in fermeture_epsilon[etat]: etats_destination.extend( self.__etats_destination(etat_epsilon, symbole)) destination_resultat = list() for etat_destination in set(etats_destination): destination_resultat.extend( self.epsilon_fermeture(etat_destination)) for destination in set(destination_resultat): nouvelle_transition = Transition(etat, symbole, destination) transition.append(nouvelle_transition) resultat = Automate(Alphabet(self.alphabet.list), list(self.etats), self.etat_initial, etat_finaux, transition) resultat.parents = self.parents.copy() resultat.nom = self.nom return resultat
def complementation_automate(self): new_transition = set() for i in self.__transitions: new_transition.add(Transition(i.arrive, i.symbole, i.depart)) return Automate(self.__alphabet, self.__etats, self.__etat_initial, [self.etat_initial], new_transition)
def a_partir_du_symbole(symbole): if not isinstance(symbole, str): raise TypeError('Un symbole dois etre de type str') alphabet = Alphabet([symbole]) initial = GenerateurAutomate.etat_initial() final = GenerateurAutomate.etat_final() transition = Transition(initial,symbole,final) return Automate(alphabet,[initial,final],initial,[final],[transition])
class AlphabetTestCase(unittest.TestCase): def setUp(self): self.a = Etat('a') self.b = Etat('b') self.t = Transition(self.a,'',self.b); def test_verification(self): self.assertEqual(self.t, Transition(self.a,'€',self.b)) self.assertEqual(self.t, Transition(self.a,'',self.b)) self.assertNotEqual(self.t, Transition(self.a,'e',self.b)) self.assertNotEqual(Transition(self.b,'e',self.a), Transition(self.a,'e',self.b)) self.assertEqual(Transition(self.b,'e',self.a), Transition(self.b,'e',self.a)) def test_epsilon(self): self.assertTrue(self.t.est_epsilon()) self.assertTrue(Transition(self.a,'€',self.b)) self.t.changer_symbole('e') self.assertFalse(self.t.est_epsilon())
def iter(self, value: str): self.ajouter_symbole(str(value)) if self.etat_initial is None or len(self.etats_finaux) == 0: self.__etat_initial = Etat(f'i{self.statecount}') self.__etat_finaux = [Etat(f'f{self.statecount}')] self.ajouter_etats(Etat(f'i{self.statecount}')) self.ajouter_etats(Etat(f'f{self.statecount}')) trans = Transition(self.etat_initial, str(value), list(self.etats_finaux)[-1]) self.ajoute_transition(trans) Automate.statecount += 1 else: s = Etat(f'S{self.statecount}') final = list(self.etats_finaux)[-1] self.ajouter_etats(s) trans = Transition(final, str(value), s) self.__etat_finaux = [s] self.ajoute_transition(trans)
def action_create_transition(self): depart = self.etatDepartBox.currentText() symbole = self.symbolBox.currentText() arrive = self.etatArriveBox.currentText() depart = Etat(depart) arrive = Etat(arrive) symbole = '' if self.epsilonCheck.isChecked() else symbole transition = Transition(depart, symbole, arrive) self.automate.ajoute_transition(transition)
def union_automate(self, automate): automate_1 = self.completer() if isinstance(automate, Automate): automate_2 = automate.completer() new_alphabet = set() for i in automate_1.alphabet.list: new_alphabet.add(i) for i in automate_2.alphabet.list: new_alphabet.add(i) new_alphabet = Alphabet(new_alphabet) new_transition = automate_1.transitions.union( automate_2.transitions) new_etat = automate_1.etats.union(automate_2.etats) new_etat.add(Etat('start')) new_transition.add( Transition(Etat('start'), '', automate_1.etat_initial)) new_transition.add( Transition(Etat('start'), '', automate_2.etat_initial)) new_finaux = automate_1.etats_finaux.union(automate_2.etats_finaux) return Automate(new_alphabet, new_etat, Etat('start'), new_finaux, new_transition)
def completer(self): if self.type != Type.AFD: return self.determiniser().completer() puit = Etat("PUIS") etats = self.etats etats.add(puit) transitions = self.transitions for etat in etats: for symbole in self.__alphabet.list: if not self.__etats_destination(etat, symbole): self.transitions.add(Transition(etat, symbole, puit)) return Automate(self.alphabet, etats, self.etat_initial, self.etats_finaux, transitions)
def determiniser(self): etats = [self.etat_initial] nouveau_vers_ancien_etat = {self.etat_initial: [self.etat_initial]} etats_finaux = set() transitions = set() etats_verifier = set() if self.type == Type.AFD: return self elif self.type == Type.AFN: if self.etat_initial in self.etats_finaux: etats_finaux.add(self.etat_initial) for etat in etats: print(f'je verifie {etat} => {nouveau_vers_ancien_etat[etat]}') if etat in etats_verifier: continue for symbol in self.alphabet.list: etats_destination = list() for ancien_etat in nouveau_vers_ancien_etat[etat]: etats_destination.extend( self.__etats_destination(ancien_etat, symbol)) print(f'etat destination {etats_destination}') if etats_destination: nouvelle_destination = Etat(''.join( [str(x) for x in etats_destination])) etats.append(nouvelle_destination) nouveau_vers_ancien_etat[nouvelle_destination] = list( set(etats_destination)) if set(etats_destination).intersection( self.etats_finaux): etats_finaux.add(nouvelle_destination) nouvelle_transition = Transition( etat, symbol, nouvelle_destination) transitions.add(nouvelle_transition) etats_verifier.add(etat) return Automate(self.__alphabet, etats_verifier, self.etat_initial, etats_finaux, list(transitions)) else: return self.convertir_en_nfa().determiniser()
def completer(self): if self.est_complet: return self if self.type != Type.AFD: return self.determiniser().completer() puit = Etat("PUIS") etats = list(self.etats) etats.append(puit) transitions = list(self.transitions) for etat in etats: for symbole in self.__alphabet.list: if not self.__etats_destination(etat, symbole): transitions.append(Transition(etat, symbole, puit)) resultat = Automate(Alphabet(self.alphabet.list), etats, self.etat_initial, self.etats_finaux.copy(), transitions) resultat.parents = self.parents.copy() resultat.nom = self.nom return resultat
def minimiser(self): if self.type != Type.AFD: return self.determiniser().minimiser() paire_etat = list() paire_traite = list() etats_temporaire = self.etats.copy() for etat in self.etats: etats_temporaire.remove(etat) for etat_temporaire in etats_temporaire: pair = {etat, etat_temporaire} paire_etat.append(frozenset(pair)) # Scanning pairs and marking a_state_has_been_marked = False for pair in paire_etat: if len(pair.intersection(self.etats_finaux)) == 1: print(f"paire chosi {pair}") paire_traite.append(frozenset(pair)) a_state_has_been_marked = True while a_state_has_been_marked: a_state_has_been_marked = False for pair in paire_etat: if pair not in paire_traite: local_pair = list(pair) for symbol in self.alphabet.list: paire_resultat = set() a = self.__etats_destination(local_pair[0], symbol) b = self.__etats_destination(local_pair[-1], symbol) print( f"paire {pair} : {local_pair[0]} sur {symbol} => {a} " ) print( f"paire {pair} : {local_pair[1]} sur {symbol} => {b} " ) if a and b: paire_resultat = set(a + b) if paire_resultat in paire_traite: print(f'nouvelle pair => {pair}') paire_traite.append(frozenset(pair)) a_state_has_been_marked = True break # Generating new set of states unmarked_pair = set(paire_etat).difference(set(paire_traite)) print(f'paire non traite {unmarked_pair}') etats_utiliser = set() new_states = set() nouveau_vers_ancien_etat = dict() for etat in self.etats: etat_ajouter = False etat_actuel = etat if etat in etats_utiliser: continue for pair in unmarked_pair: if etat_actuel in pair: etats_utiliser.update({x for x in pair}) print(f"etat utiliser = {etats_utiliser}") nouvel_etat = Etat(','.join([str(x) for x in pair])) nouveau_vers_ancien_etat[nouvel_etat] = pair new_states.add(nouvel_etat) etat_ajouter = True if not etat_ajouter: new_states.add(etat_actuel) nouveau_vers_ancien_etat[etat_actuel] = [etat_actuel] #print(f"nouveau_vers_ancien_etat") print(f"Nouvelle etats {new_states}") # Generation new set of transitions read_trans = list() new_transitions = set() new_initial_state = set() new_final_states = set() for state in new_states: if self.etat_initial in nouveau_vers_ancien_etat[state]: new_initial_state = state print(f"Nouvel etat initial {state}") for f_state in self.etats_finaux: if f_state in nouveau_vers_ancien_etat[state]: new_final_states.add(state) for transition in self.transitions: _from = transition.depart _to = transition.arrive _on = transition.symbole if (_from, _on) in read_trans: continue for state in new_states: if _from in nouveau_vers_ancien_etat[state]: result = self.__etats_destination(_from, _on) read_trans.append((_from, _on)) for result_state in result: for i in new_states: if result_state in nouveau_vers_ancien_etat[i]: trans = Transition(state, _on, i) new_transitions.add(trans) resultat = Automate(Alphabet(self.alphabet.list), new_states, new_initial_state, new_final_states, list(new_transitions)) resultat.parents = self.parents.copy() resultat.nom = self.nom return resultat
def etats_finaux(self): return self.__etat_finaux @property def transitions(self): return self.__transitions if __name__ == '__main__': alphabet = Alphabet(['a', 'b']) alphabet2 = Alphabet(['m']) a = Etat('q1') b = Etat('q2') c = Etat('q3') e = Etat('q4') f = Etat('q5') t1 = Transition(a, 'a', b) t2 = Transition(b, 'b', c) t3 = Transition(c, 'a', b) t4 = Transition(e, 'm', f) automate = Automate(alphabet, [a, b, c], a, [b], [t1, t2, t3]) automate2 = Automate(alphabet2, [e, f], e, [f], [t4]) print(automate.alphabet) automate.definir_nom('hiro') print(automate.nom) automate.visualiser() automate.complementation_automate().visualiser() #automate2.visualiser() #automate.union_automate(automate).visualiser() #automate.union_automate(automate).determiniser().visualiser()
nouvel_alphabet = Alphabet( [*automate1.alphabet.list, *automate2.alphabet.list]) automate = Automate(nouvel_alphabet, nouveaux_etats, initial, [final], nouvelle_transition) return automate @staticmethod def etat(): GenerateurAutomate.compteur_etat += 1 return Etat(f'Q{GenerateurAutomate.compteur_etat}') @staticmethod def etat_initial(): GenerateurAutomate.compteur_etat_initial += 1 return Etat(f'I{GenerateurAutomate.compteur_etat_initial}') @staticmethod def etat_final(): GenerateurAutomate.compteur_etat_final += 1 return Etat(f'F{GenerateurAutomate.compteur_etat_final}') if __name__ == '__main__': a = Automate(Alphabet(['1']), [Etat('a'), Etat('b')], Etat('a'), [Etat('b')], [Transition(Etat('a'), '1', Etat('b'))]) b = Automate(Alphabet(['2']), [Etat('c'), Etat('d')], Etat('c'), [Etat('d')], [Transition(Etat('c'), '2', Etat('d'))]) a.visualiser() b.visualiser() GenerateurAutomate.faire_kleen(a).visualiser()
def setUp(self): self.a = Etat('a') self.b = Etat('b') self.t = Transition(self.a,'',self.b);
def determiniser(self): etats = [self.etat_initial] nouveau_vers_ancien_etat = {self.etat_initial: [self.etat_initial]} etats_finaux = set() transitions = set() etats_verifier = set() if self.type == Type.AFD: return self elif self.type == Type.AFN: if self.etat_initial in self.etats_finaux: etats_finaux.add(self.etat_initial) for etat in etats: print('Je boucle a partir de ici') print(f'je verifie {etat} => {nouveau_vers_ancien_etat[etat]}') if etat in etats_verifier: continue for symbol in self.alphabet.list: etats_destination = list() for ancien_etat in nouveau_vers_ancien_etat[etat]: etats_destination.extend( self.__etats_destination(ancien_etat, symbol)) print(f'etat destination {etats_destination}') if etats_destination: should_add = True for i in nouveau_vers_ancien_etat: if set(etats_destination) == set( nouveau_vers_ancien_etat[i]): should_add = False nouvelle_destination = i if not should_add: break #nouvelle_destination = Etat(','.join([str(x) for x in etats_destination])) if should_add: nouvelle_destination = Etat( '{' + ','.join([str(x) for x in etats_destination]) + '}') #nouvelle_destination = Automate.genere_etat() etats.append(nouvelle_destination) nouveau_vers_ancien_etat[ nouvelle_destination] = list( set(etats_destination)) if set(etats_destination).intersection( self.etats_finaux): etats_finaux.add(nouvelle_destination) #etats_verifier.add(nouvelle_destination) nouvelle_transition = Transition( etat, symbol, nouvelle_destination) transitions.add(nouvelle_transition) etats_verifier.add(etat) resultat = Automate(self.__alphabet, etats_verifier, self.etat_initial, etats_finaux, list(transitions)) resultat.parents = self.parents.copy() resultat.nom = self.nom return resultat else: return self.convertir_en_nfa().determiniser()
def test_epsilon(self): self.assertTrue(self.t.est_epsilon()) self.assertTrue(Transition(self.a,'€',self.b)) self.t.changer_symbole('e') self.assertFalse(self.t.est_epsilon())
def test_verification(self): self.assertEqual(self.t, Transition(self.a,'€',self.b)) self.assertEqual(self.t, Transition(self.a,'',self.b)) self.assertNotEqual(self.t, Transition(self.a,'e',self.b)) self.assertNotEqual(Transition(self.b,'e',self.a), Transition(self.a,'e',self.b)) self.assertEqual(Transition(self.b,'e',self.a), Transition(self.b,'e',self.a))
if ok: a = Automate(Alphabet([]), [], None, [], []) a.definir_nom(text) try: self.liste_automate[text] = a except: self.liste_automate[text + '(1)'] = a self.creation.ui.createBtn.setState() self.automate.copie_automate(a) alphabet = Alphabet(['1', '2', '3']) a = Etat('a') b = Etat('b') c = Etat('c') t1 = Transition(a, '1', b) t2 = Transition(a, '1', a) t3 = Transition(a, '2', b) t4 = Transition(b, '1', b) automata = Automate(alphabet, [a, b, c], a, [a, c], [t1, t2, t3, t4]) automata.definir_nom('Brains') def run_app(automate=automata): import sys app = QtWidgets.QApplication(sys.argv) MainWindow = QtWidgets.QMainWindow() ui = Ui_MainWindow(automata) ui.setupUi(MainWindow) MainWindow.show()