def intersection(aut1, aut2): aut1 = completer(aut1) aut2 = completer(aut2) alpha = list(aut1.get_alphabet() - aut1.get_epsilons()) if alpha != list(aut2.get_alphabet() - aut2.get_epsilons()): return automaton() #Tous les états etats1 = list(aut1.get_states()) etats2 = list(aut2.get_states()) etats = produit_cartesien(etats1, etats2) # les etats initiaux ini1 = list(aut1.get_initial_states()) ini2 = list(aut2.get_initial_states()) ini = produit_cartesien(ini1, ini2) #lLes etats finaux fin1 = list(aut1.get_final_states()) fin2 = list(aut2.get_final_states()) fin = produit_cartesien(fin1, fin2) trans = nouvelles_transitions_IU(aut1, aut2, etats1, etats2, alpha) a = automaton(alphabet=alpha, states=etats, initials=ini, finals=fin, transitions=trans) a.renumber_the_states() return a
def intersection(aut1,aut2) : aut1 = completer(aut1) aut2 = completer(aut2) alpha = list(aut1.get_alphabet() - aut1.get_epsilons() ) if alpha != list( aut2.get_alphabet() - aut2.get_epsilons() ) : return automaton() #Tous les états etats1 = list( aut1.get_states() ) etats2 = list( aut2.get_states() ) etats = produit_cartesien(etats1,etats2) # les etats initiaux ini1 = list( aut1.get_initial_states() ) ini2 = list( aut2.get_initial_states() ) ini = produit_cartesien(ini1,ini2) #lLes etats finaux fin1 = list( aut1.get_final_states() ) fin2 = list( aut2.get_final_states() ) fin = produit_cartesien(fin1,fin2) trans = nouvelles_transitions_IU(aut1, aut2,etats1,etats2,alpha) a = automaton(alphabet = alpha, states = etats, initials = ini, finals = fin, transitions = trans ) a.renumber_the_states() return a
def determiniser(Aut): """ This function returns the equivalent deterministic automaton of the one given. """ if is_deterministic(Aut): return Aut A = suppress_epsilon_transitions(Aut) initials = A.get_initial_states() finals = A.get_final_states() alphabet = A.get_alphabet() B = automaton() start = pretty_set(initials) B.add_initial_state(start) state_to_compute = [start] state_computed = [] while state_to_compute: state = state_to_compute[0] successor = {x: set() for x in alphabet} for substate in state: for a in alphabet: successor[a] = successor[a].union(A.delta(a, [substate])) for key in successor: successor_set = pretty_set(successor[key]) if successor_set not in state_computed and successor_set not in state_to_compute: state_to_compute.append(successor_set) B.add_transition((state, key, successor_set)) state_to_compute.remove(state) state_computed.append(state) for state in state_computed: for substate in state: if substate in finals: B.add_final_state(state) return B
def determiniser(aut): ini = aut.get_initial_states( ) # nouvelle etat defini par l'ensemble des etats initiaux states = [ini] #liste des nouveaux états trans = [] alpha = aut.get_alphabet() - aut.get_epsilons() l = [ini] # on enfile cette etat, dans la file des etats a traiter while (len(l) != 0): # tant qu'on a des etats a traiter for i in alpha: # pour chaque lettre tmp = aut.delta(i, l[0]) #on defini l'etat qu'il peut rejoindre if len(tmp) != 0: #s'il y en a trans += [(l[0], i, tmp)] #on crée la transitions if not tmp in states: #et s'il n'a jamais été vu, on le rajoute states += [tmp] l += [tmp] l.pop(0) #on defile l'etat traiter oldFinals = aut.get_final_states() fin = [] for i in states: for j in i: if j in oldFinals: #pour chaque nouveaux sommet, si un des sommets qui le définie est final, il devient final fin += [i] break a = automaton(alphabet=alpha, states=states, initials=[ini], finals=fin, transitions=trans) a.renumber_the_states() return a
def determiniser( aut ) : ini = aut.get_initial_states() # nouvelle etat defini par l'ensemble des etats initiaux states = [ini] #liste des nouveaux états trans = [] alpha = aut.get_alphabet() - aut.get_epsilons() l = [ini] # on enfile cette etat, dans la file des etats a traiter while( len(l) != 0 ) : # tant qu'on a des etats a traiter for i in alpha : # pour chaque lettre tmp = aut.delta(i,l[0]) #on defini l'etat qu'il peut rejoindre if len(tmp) != 0 : #s'il y en a trans += [ ( l[0] , i , tmp ) ] #on crée la transitions if not tmp in states : #et s'il n'a jamais été vu, on le rajoute states += [tmp] l += [tmp] l.pop(0) #on defile l'etat traiter oldFinals = aut.get_final_states() fin = [] for i in states : for j in i : if j in oldFinals : #pour chaque nouveaux sommet, si un des sommets qui le définie est final, il devient final fin += [i] break a = automaton( alphabet = alpha, states = states, initials = [ini], finals = fin, transitions = trans) a.renumber_the_states() return a
def delete_state(Aut, state): alpha = list(Aut.get_alphabet()) s = list(Aut.get_states()) if state not in s: return Aut else: s.remove(state) init = list(Aut.get_initial_states()) if state in init: init.remove(state) fin = list(Aut.get_final_states()) if state in fin: fin.remove(state) trans = list(Aut.get_transitions()) i = 0 while i != len(trans): if trans[i][0] == state or trans[i][2] == state: trans.pop(i) else: i += 1 return automaton(epsilons=Aut.get_epsilons(), alphabet=alpha, states=s, initials=init, finals=fin, transitions=trans)
def delete_state( Aut, state ) : alpha = list(Aut.get_alphabet()) s = list(Aut.get_states()) if state not in s : return Aut else : s.remove(state) init = list(Aut.get_initial_states()) if state in init : init.remove(state) fin = list(Aut.get_final_states()) if state in fin : fin.remove(state) trans = list(Aut.get_transitions()) i = 0 while i != len(trans) : if trans[i][0] == state or trans[i][2] == state : trans.pop(i) else : i+=1 return automaton( epsilons = Aut.get_epsilons(), alphabet = alpha, states = s, initials = init, finals = fin, transitions = trans)
def minimiser( Aut ) : Aut2 = completer( Aut ) Aut2 = determiniser( Aut2 ) etats = list(Aut2.get_states()) alpha = list(Aut2.get_alphabet()) # Initialisation. On sépare les états finaux du reste. lm1 = list() for i in range(len(etats)) : if Aut2.state_is_final(etats[i]) : lm1.append(tuple((1,))) else : lm1.append(tuple((0,))) for j in range(len(alpha)) : d = list(Aut2.delta(alpha[j], [ etats[i] ])) if Aut2.state_is_final(d[0]) : lm1[i] = lm1[i] + tuple((1,)) else : lm1[i] = lm1[i] + tuple((0,)) # On applique l'algorithme de Moore tant que la liste # n'est pas stable. lm2 = moore(Aut2, etats, alpha, lm1) while lm1 != lm2 : lm1 = lm2 lm2 = moore(Aut2, etats, alpha, lm1) # On récupère l'état initial. init = lm2[etats.index(list(Aut2.get_initial_states())[0])][0] # On recherche les nouveaux états finaux. lm1 = list() ets = list() for i in range(len(etats)) : if Aut2.state_is_final(etats[i]) : lm1.append(lm2[i][0]) ets.append(lm2[i][0]) # On enlève les doublons # lm1 la liste des états finaux. # lm2 la totalité des états et des transitions. # ets la liste de tous les états. lm1 = list(set(lm1)) lm2 = list(set(lm2)) ets = list(set(ets)) amin = automaton( alphabet = alpha, states = ets, initials = [init], finals = lm1) # On récupère les nouvelles transitions. for i in range(len(lm2)) : for j in range(len(alpha)) : amin.add_transition( (lm2[i][0], alpha[j], lm2[i][j + 1]) ) return amin
def minimiser(Aut): Aut2 = completer(Aut) Aut2 = determiniser(Aut2) etats = list(Aut2.get_states()) alpha = list(Aut2.get_alphabet()) # Initialisation. On sépare les états finaux du reste. lm1 = list() for i in range(len(etats)): if Aut2.state_is_final(etats[i]): lm1.append(tuple((1, ))) else: lm1.append(tuple((0, ))) for j in range(len(alpha)): d = list(Aut2.delta(alpha[j], [etats[i]])) if Aut2.state_is_final(d[0]): lm1[i] = lm1[i] + tuple((1, )) else: lm1[i] = lm1[i] + tuple((0, )) # On applique l'algorithme de Moore tant que la liste # n'est pas stable. lm2 = moore(Aut2, etats, alpha, lm1) while lm1 != lm2: lm1 = lm2 lm2 = moore(Aut2, etats, alpha, lm1) # On récupère l'état initial. init = lm2[etats.index(list(Aut2.get_initial_states())[0])][0] # On recherche les nouveaux états finaux. lm1 = list() ets = list() for i in range(len(etats)): if Aut2.state_is_final(etats[i]): lm1.append(lm2[i][0]) ets.append(lm2[i][0]) # On enlève les doublons # lm1 la liste des états finaux. # lm2 la totalité des états et des transitions. # ets la liste de tous les états. lm1 = list(set(lm1)) lm2 = list(set(lm2)) ets = list(set(ets)) amin = automaton(alphabet=alpha, states=ets, initials=[init], finals=lm1) # On récupère les nouvelles transitions. for i in range(len(lm2)): for j in range(len(alpha)): amin.add_transition((lm2[i][0], alpha[j], lm2[i][j + 1])) return amin
def miroir(Aut): """ This function compute and returns the miror of the given autamaton. """ initials = Aut.get_initial_states() finals = Aut.get_final_states() transit = list(Aut.get_transitions()) A = automaton(initials=finals, finals=initials) for t in transit: A.add_transition(tuple(reversed(t))) return A
def automaton_with_cartesian_product(A, B, union_or_intersect=0): """ This function returns the union or the intersection of two automata if keyword union_or_intersect = 0 , the union of returned, intersection is returned otherwise TODO: use set comprehension generation , add keyword parameter to specify either union or intersection """ if A.get_alphabet() != B.get_alphabet(): print("/!\\Automaton don't have the same alphabet /!\\") sys.exit() if is_deterministic(A): new_A = completer(A) else: new_A = determiniser(A) new_A.renumber_the_states() if is_deterministic(B): new_B = completer(B) else: new_B = determiniser(B) new_B.renumber_the_states() states_of_A = new_A.get_states() initials_of_A = new_A.get_initial_states() finals_of_A = new_A.get_final_states() states_of_B = new_B.get_states() initials_of_B = new_B.get_initial_states() finals_of_B = new_B.get_final_states() product_aut = automaton() for s in states_of_A: for t in states_of_B: for a in A.get_alphabet(): x = list(new_A.delta(a, [s])) x.extend(list(new_B.delta(a, [t]))) x_y_tuple = tuple(x) product_aut.add_transition(((s, t), a, x_y_tuple)) if s in initials_of_A and t in initials_of_B: product_aut.add_initial_state((s, t)) states_product_aut = product_aut.get_states() if union_or_intersect == 0: for state in states_product_aut: if state[0] in finals_of_A or state[1] in finals_of_B: product_aut.add_final_state(state) else: for state in states_product_aut: if state[0] in finals_of_A and state[1] in finals_of_B: product_aut.add_final_state(state) return product_aut
def union( Aut1, Aut2 ) : Aut1 = completer(Aut1) Aut2 = completer(Aut2) alpha = list(Aut1.get_alphabet() - Aut1.get_epsilons()) if alpha != list( Aut2.get_alphabet() - Aut2.get_epsilons() ) : return automaton() # Tous les états. et1 = list(Aut1.get_states()) et2 = list(Aut2.get_states()) et = produit_cartesien(et1, et2) # Les états finaux. f1 = produit_cartesien(list(Aut1.get_final_states()), et2) f2 = produit_cartesien(et1, list(Aut2.get_final_states())) for i in range(len(f1)) : if f1[i] not in f2 : f2.append(f1[i]) # Les états initiaux. ini = produit_cartesien(list(Aut1.get_initial_states()), list(Aut2.get_initial_states())) tr = nouvelles_transitions_IU(Aut1, Aut2, et1, et2, alpha) u = automaton( alphabet = alpha, states = et, initials = ini, finals = f2, transitions = tr) u.renumber_the_states() return u
def union(Aut1, Aut2): Aut1 = completer(Aut1) Aut2 = completer(Aut2) alpha = list(Aut1.get_alphabet() - Aut1.get_epsilons()) if alpha != list(Aut2.get_alphabet() - Aut2.get_epsilons()): return automaton() # Tous les états. et1 = list(Aut1.get_states()) et2 = list(Aut2.get_states()) et = produit_cartesien(et1, et2) # Les états finaux. f1 = produit_cartesien(list(Aut1.get_final_states()), et2) f2 = produit_cartesien(et1, list(Aut2.get_final_states())) for i in range(len(f1)): if f1[i] not in f2: f2.append(f1[i]) # Les états initiaux. ini = produit_cartesien(list(Aut1.get_initial_states()), list(Aut2.get_initial_states())) tr = nouvelles_transitions_IU(Aut1, Aut2, et1, et2, alpha) u = automaton(alphabet=alpha, states=et, initials=ini, finals=f2, transitions=tr) u.renumber_the_states() return u
def miroir( Aut ) : trans = list( Aut.get_transitions() ) newTrans = [] for i in range( len(trans) ) : newTrans = newTrans + [(trans[i][2], trans[i][1], trans[i][0] )] #chaque transitions de la forme (x,a,y) et remplacé par la trnsition (y,a,x) a = automaton( epsilons = Aut.get_epsilons(), alphabet = Aut.get_alphabet(), states = Aut.get_states(), initials = Aut.get_final_states(), # les etats finaux deviennent initiaux finals = Aut.get_initial_states(), #les etats initiaux deviennent finaux transitions = newTrans ) return a
def complement(Aut): """" This function returns the complement of the given automaton. """ if is_deterministic(Aut): B = completer(Aut) else: B = determiniser(Aut) transitions = B.get_transitions() initials = B.get_initial_states() finals = B.get_final_states() states = B.get_states() non_finals = states - finals return automaton(initials=initials, finals=non_finals, transitions=transitions)
def operation(expr) : if len(expr) != 0 : if expr[0] == '*' : return etoile(expr[1]) elif expr[0] == '+' : return unionEVA(expr[1],expr[2]) elif expr[0] == '.' : return concatenation(expr[1],expr[2]) elif len(expr) == 1 : return automaton(alphabet = expr, states = [1,2], initials = [1], finals = [2], transitions = [ (1 , expr , 2) ] ) return None
def operation(expr): if len(expr) != 0: if expr[0] == '*': return etoile(expr[1]) elif expr[0] == '+': return unionEVA(expr[1], expr[2]) elif expr[0] == '.': return concatenation(expr[1], expr[2]) elif len(expr) == 1: return automaton(alphabet=expr, states=[1, 2], initials=[1], finals=[2], transitions=[(1, expr, 2)]) return None
def complement(aut): a = completer(determiniser(aut)) oldFinals = a.get_final_states() fin = [] """ Pour chaque sommet, s'il n'etait pas final, il le devient. """ for i in a.get_states(): if not i in oldFinals: fin += [i] return automaton(alphabet=a.get_alphabet(), states=a.get_states(), initials=a.get_initial_states(), finals=fin, transitions=a.get_transitions())
def miroir(Aut): trans = list(Aut.get_transitions()) newTrans = [] for i in range(len(trans)): newTrans = newTrans + [ (trans[i][2], trans[i][1], trans[i][0]) ] #chaque transitions de la forme (x,a,y) et remplacé par la trnsition (y,a,x) a = automaton( epsilons=Aut.get_epsilons(), alphabet=Aut.get_alphabet(), states=Aut.get_states(), initials=Aut.get_final_states( ), # les etats finaux deviennent initiaux finals=Aut.get_initial_states(), #les etats initiaux deviennent finaux transitions=newTrans) return a
def complement( aut ) : a = completer(determiniser( aut ) ) oldFinals = a.get_final_states() fin = [] """ Pour chaque sommet, s'il n'etait pas final, il le devient. """ for i in a.get_states() : if not i in oldFinals : fin += [i] return automaton( alphabet = a.get_alphabet(), states = a.get_states(), initials = a.get_initial_states(), finals = fin, transitions = a.get_transitions())
def etoile(expr) : aut = operation(expr) # on recupere l'automate defini par expr. """ On crée les etats nécessaires. """ s1 = aut.get_maximal_id() if s1 == None : s1 = 0 else : s1 += 1 s2 = s1 + 1 s3 = s2 + 1 s4 = s3 + 1 alpha = aut.get_alphabet() #On récupère un charactère definissant epsilons. if(aut.has_epsilon_characters()) : epsilon = list(aut.get_epsilons())[0] else : epsilon = generer_epsilon(alpha) #on genere les nouvelles transitions nécessaire. transitions = list( aut.get_transitions() ) transitions += [ (s1 , epsilon , s2) , (s1 , epsilon , s4) , (s3 , epsilon , s2) , (s3 , epsilon , s4) ] for i in aut.get_initial_states() : transitions += [ (s2 , epsilon , i ) ] for i in aut.get_final_states() : transitions += [ ( i , epsilon , s3 ) ] return automaton( alphabet = alpha, epsilons = [epsilon] + list(aut.get_epsilons()) , states = list(aut.get_states()) + [s1 , s2 , s3, s4] , initials = [s1] , finals = [s4], transitions = transitions)
def etoile(expr): aut = operation(expr) # on recupere l'automate defini par expr. """ On crée les etats nécessaires. """ s1 = aut.get_maximal_id() if s1 == None: s1 = 0 else: s1 += 1 s2 = s1 + 1 s3 = s2 + 1 s4 = s3 + 1 alpha = aut.get_alphabet() #On récupère un charactère definissant epsilons. if (aut.has_epsilon_characters()): epsilon = list(aut.get_epsilons())[0] else: epsilon = generer_epsilon(alpha) #on genere les nouvelles transitions nécessaire. transitions = list(aut.get_transitions()) transitions += [(s1, epsilon, s2), (s1, epsilon, s4), (s3, epsilon, s2), (s3, epsilon, s4)] for i in aut.get_initial_states(): transitions += [(s2, epsilon, i)] for i in aut.get_final_states(): transitions += [(i, epsilon, s3)] return automaton(alphabet=alpha, epsilons=[epsilon] + list(aut.get_epsilons()), states=list(aut.get_states()) + [s1, s2, s3, s4], initials=[s1], finals=[s4], transitions=transitions)
def suppress_epsilon_transitions(Aut): """ This function returns the equivalent automaton of the given one with e-move suppressed. """ initials = Aut.get_initial_states() finals = Aut.get_final_states() states = Aut.get_states() epsilon_set = Aut.get_epsilons() alphabet = Aut.get_alphabet() A = automaton(initials=initials, finals=finals, states=states) valid_alphabet = alphabet - epsilon_set transition_list = [list(x) for x in Aut.get_transitions()] # add all transitions except e-transitions for l in transition_list: if l[1] in valid_alphabet: A.add_transition(tuple(l)) for s in states: next_by_e_move = [] for e in epsilon_set: item = Aut.delta(e, [s]) item = [x for x in item] next_by_e_move.extend(item) if s in next_by_e_move: next_by_e_move.remove(s) for a in valid_alphabet: successor = [] for after in next_by_e_move: item = Aut.delta(a, [after], ignore_epsilons=True) successor.extend(item) for succ in successor: A.add_transition((s, a, succ)) if after in finals: A.add_final_states([s]) return A
def intersection(self, aut2, destructif=False): """ Calcule l'intersection de deux automates. Le paramètre "destructif" rend destructive la méthode sur le premier automate. Par défaut, la méthode ne modifie pas le premier automate """ assert self.get_alphabet() == aut2.get_alphabet(), "Les deux automates n'ont pas le meme alphabet" assert self.get_epsilons() == aut2.get_epsilons(), "Les epsilons ne sont pas encodees par les memes caracteres" automate_clone = self.clone() # On travaille sur des automates deterministes if not aut2.est_deterministe(): aut2 = aut2.determinisation() if not self.est_deterministe(): automate_clone = self.determinisation(destructif) # On travaille sur des automates complet if not aut2.est_complet(): aut2 = aut2.completer() if not self.est_complet(): automate_clone = self.completer(destructif) alphabet_courant = self.get_alphabet() automate_tmp = automaton( alphabet= alphabet_courant, epsilons= self.get_epsilons() ) finaux_1 = automate_clone.get_final_states() finaux_2 = aut2.get_final_states() # Création états initiaux de l'automate de l'union for ini_1 in automate_clone.get_initial_states(): for ini_2 in aut2.get_initial_states(): etat = (ini_1, ini_2) automate_tmp.add_initial_state(etat) # Création de l'automate des couples (automate de l'union) for etat_1 in automate_clone.get_states(): for etat_2 in aut2.get_states(): automate_tmp.add_state((etat_1, etat_2)) for lettre in alphabet_courant: for dest_1 in automate_clone.delta(lettre, [etat_1]): for dest_2 in aut2.delta(lettre, [etat_2]): automate_tmp.add_transition(((etat_1, etat_2), lettre, (dest_1, dest_2))) if etat_1 in finaux_1 and etat_2 in finaux_2: automate_tmp.add_final_state((etat_1, etat_2)) ################## ANCIENNE IMPLÉMENTATION ################################## # while len(pile_etats) > 0: # etat_courant = pile_etats.pop() # if not etat_courant == set(): # etat_1, etat_2 = etat_courant # for l in self.get_alphabet(): # if not l in self.get_epsilons(): # delta_etat_1 = self._delta(l, [etat_1]) # delta_etat_2 = aut2._delta(l, [etat_2]) # nouveau = set() # for e1 in delta_etat_1: # for e2 in delta_etat_2: # nouveau = (e1,e2) # if not nouveau == set(): # if not nouveau in automate_tmp.get_states(): # pile_etats.append(nouveau) # final = True # for e in nouveau: # if not e in finaux: # final = False # break # if final: # automate_tmp.add_final_state(nouveau) # automate_tmp.add_transition((etat_courant, l, nouveau)) if destructif: self.reconstruction(automate_tmp) return automate_tmp
def minimiser_moore(Aut): """" This function returns the minimize automaton of the given one by using moore algorithm. """ if is_deterministic(Aut): B = completer(Aut) else: B = determiniser(Aut) B.renumber_the_states() B.map(lambda x: x - 1) alphabet = B.get_alphabet() card_alphabet = len(alphabet) states = B.get_states() maxi = B.get_maximal_id() states_list = [x for x in range(maxi + 1)] destination_reference = [[] for _ in range(len(alphabet))] i = 0 for a in alphabet: destination_reference[i] = [] for s in states_list: l = B.delta(a, [s]) l = [x for x in l][0] destination_reference[i].append(l) i += 1 equivalence_classes = [0 for x in states] for i in range(maxi + 1): if B.state_is_final(i): equivalence_classes[i] = 1 pre_equivalence_classes = [] while pre_equivalence_classes != equivalence_classes: class_number = 0 mark_array = [False for _ in range(maxi + 1)] pre_equivalence_classes = [x for x in equivalence_classes] # going through the states for i in range(maxi + 1): if mark_array[i] == True: continue eq_per_loop = [i] list_tuple = [pre_equivalence_classes[i]] # going through the alphabet for j in range(card_alphabet): # first get the successor of i by j and then compute his equivalence_class list_tuple.append(pre_equivalence_classes[destination_reference[j][i]]) # check if other states have the same list , if so then the two are in same eq_class for k in range(i + 1, maxi + 1): inner_list_tuple = [pre_equivalence_classes[k]] # going again through the alphabet for l in range(card_alphabet): inner_list_tuple.append(pre_equivalence_classes[destination_reference[l][k]]) # same class if list_tuple == inner_list_tuple: eq_per_loop.append(k) # update the equivalence_classes for s in eq_per_loop: mark_array[s] = True equivalence_classes[s] = class_number class_number += 1 mini_state = {x for x in equivalence_classes} mini_state = [x for x in mini_state] # initial state of the original automaton initials = [x for x in B.get_initial_states()] # final state of the original automaton finals = [x for x in B.get_final_states()] mini_initial = equivalence_classes[initials[0]] mini_final = [] for s in finals: mini_final.append(equivalence_classes[s]) minimal_aut = automaton(states=mini_state, initials=[mini_initial], finals=mini_final, alphabet=alphabet) for s in states_list: eq_s = equivalence_classes[s] i = 0 for a in alphabet: successor_by_a = equivalence_classes[destination_reference[i][s]] minimal_aut.add_transition((eq_s, a, successor_by_a)) i += 1 return minimal_aut
def concatenation(expr1, expr2): #on renomme les états au cas où il y aurait des redondances aut1 = operation(expr1) aut2 = operation(expr2) aut1.renumber_the_states() aut2.renumber_the_states() x = aut1.get_maximal_id() if x == None: x = 0 else: x += 1 def rajouter(y): return y + x aut2.map(rajouter) #on génère le nouvel alphabet et on fusionne tous les epsilons en un même symbole, #permet d'éviter les problèmes liés au fait qu'un epsilon de aut1 #peut être dans l'alphabet de aut2, et inversement. old_epsilon1 = aut1.get_epsilons() old_epsilon2 = aut2.get_epsilons() alpha1 = list(aut1.get_alphabet() - old_epsilon1) alpha2 = list(aut2.get_alphabet() - old_epsilon2) alpha = list(aut1.get_alphabet() - old_epsilon1) for i in alpha2: if not i in alpha: alpha += [i] epsilon = generer_epsilon(alpha) transitions = [] for i in aut1.get_transitions(): if i[1] in old_epsilon1: transitions += [(i[0], epsilon, i[2])] else: transitions += [i] for i in aut2.get_transitions(): if i[1] in old_epsilon2: transitions += [(i[0], epsilon, i[2])] else: transitions += [i] #creation de l'automate concaténation s1 = aut2.get_maximal_id() if s1 == None: s1 = 0 else: s1 += 1 s2 = s1 + 1 for i in aut1.get_initial_states(): transitions += [(s1, epsilon, i)] for i in aut1.get_final_states(): for j in aut2.get_initial_states(): transitions += [(i, epsilon, j)] for i in aut2.get_final_states(): transitions += [(i, epsilon, s2)] return automaton(alphabet=alpha, epsilons=[epsilon], finals=[s2], initials=[s1], transitions=transitions)
def concatenation(expr1,expr2) : #on renomme les états au cas où il y aurait des redondances aut1 = operation(expr1) aut2 = operation(expr2) aut1.renumber_the_states() aut2.renumber_the_states() x = aut1.get_maximal_id() if x == None : x = 0 else : x+=1 def rajouter(y) : return y + x aut2.map(rajouter) #on génère le nouvel alphabet et on fusionne tous les epsilons en un même symbole, #permet d'éviter les problèmes liés au fait qu'un epsilon de aut1 #peut être dans l'alphabet de aut2, et inversement. old_epsilon1 = aut1.get_epsilons() old_epsilon2 = aut2.get_epsilons() alpha1 = list( aut1.get_alphabet() - old_epsilon1 ) alpha2 = list( aut2.get_alphabet() - old_epsilon2 ) alpha = list( aut1.get_alphabet() - old_epsilon1 ) for i in alpha2 : if not i in alpha : alpha += [i] epsilon = generer_epsilon(alpha) transitions = [] for i in aut1.get_transitions() : if i[1] in old_epsilon1 : transitions += [ ( i[0] , epsilon , i[2] ) ] else : transitions += [i] for i in aut2.get_transitions() : if i[1] in old_epsilon2 : transitions += [ ( i[0] , epsilon , i[2] ) ] else : transitions += [i] #creation de l'automate concaténation s1 = aut2.get_maximal_id() if s1 == None : s1 = 0 else : s1 += 1 s2 = s1 + 1 for i in aut1.get_initial_states() : transitions += [ (s1 , epsilon , i ) ] for i in aut1.get_final_states() : for j in aut2.get_initial_states() : transitions += [ (i , epsilon , j) ] for i in aut2.get_final_states() : transitions += [ (i , epsilon , s2) ] return automaton( alphabet = alpha , epsilons = [ epsilon ] , finals = [s2] , initials = [s1] , transitions = transitions )