00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 #ifndef VCSN_ALGORITHMS_ISOMORPH_HXX
00018 # define VCSN_ALGORITHMS_ISOMORPH_HXX
00019 
00020 # include <vaucanson/algorithms/isomorph.hh>
00021 # include <vaucanson/algorithms/determinize.hh>
00022 
00023 # include <vaucanson/automata/concept/automata_base.hh>
00024 # include <vaucanson/misc/usual_macros.hh>
00025 
00026 # include <vaucanson/algorithms/internal/skeleton.hh>
00027 
00028 # include <queue>
00029 # include <set>
00030 # include <list>
00031 # include <utility>
00032 
00033 namespace vcsn {
00034 
00035   
00036 
00037 
00038 
00039   class Trie
00040   {
00041     public:
00042       Trie* insert(std::vector<int>&);
00043 
00044     public:
00045       std::list<int> A, B;
00046 
00047       
00048       std::list<Trie*>::iterator L;
00049 
00050     private:
00051       Trie* insert_suffix(std::vector<int>&, unsigned int);
00052       std::map<int, Trie> children;
00053   };
00054 
00055   
00056   inline Trie* Trie::insert(std::vector<int>& S)
00057   {
00058     return insert_suffix(S, 0);
00059   }
00060 
00061   inline Trie* Trie::insert_suffix(std::vector<int>& S, unsigned int p)
00062   {
00063     if (p == S.capacity() - 1)
00064       return this;
00065 
00066     return children[S[p]].insert_suffix(S, p + 1);
00067   }
00068 
00069 
00070   
00071 
00072 
00073 
00074   template<typename A, typename T>
00075   bool
00076   are_isomorphic(const Element<A, T>& a, const Element<A, T>& b)
00077   {
00078     typedef Element<A, T> automaton_t;
00079 
00080     AUTOMATON_TYPES(automaton_t);
00081 
00082     
00083     if ((a.states().size() != b.states().size())
00084         || (a.transitions().size() != b.transitions().size())
00085         || (a.initial().size() != b.initial().size())
00086         || (a.final().size() != b.final().size()))
00087       return false;
00088 
00089 
00090     int i, j , k, l;
00091     bool iso;
00092     std::list<int>::iterator it_int, it_int_B, it_int_aux;
00093 
00094     
00095     
00096     
00097     std::vector<std::list<int>::iterator> T_L_A(a.states().size());
00098 
00099     
00100     std::vector<std::list<int>::iterator> T_L_B(b.states().size());
00101 
00102 
00103     
00104     Trie *T_Q_IT, *T_I, *T_T, *T_aux;
00105 
00106     T_Q_IT = new Trie();
00107     T_I = new Trie();
00108     T_T = new Trie();
00109 
00110     std::list<Trie*> C;
00111     
00112     std::list<int> U;
00113     
00114     std::vector<Trie*> class_state_A(a.states().size());
00115     
00116     std::vector<Trie*> class_state_B(b.states().size());
00117 
00118     
00119     
00120     
00121     std::vector<int> perm_A(a.states().size());
00122     std::vector<int> perm_B(b.states().size());
00123 
00124     Skeleton<A, T> Sa(a);
00125     Skeleton<A, T> Sb(b);
00126 
00127     
00128     iso = true;
00129 
00130     
00131     
00132     
00133 
00134     std::vector< std::list<int> > delta_det_in_A(a.states().size());
00135     std::vector< std::list<int> > delta_det_out_A(a.states().size());
00136     std::vector< std::list<int> > delta_det_in_B(b.states().size());
00137     std::vector< std::list<int> > delta_det_out_B(b.states().size());
00138 
00139     
00140     for (i = 0; i < static_cast<int>(a.states().size()); i++)
00141     {
00142       if ((Sa.delta_in[i]).size() > 0)
00143       {
00144         it_int = Sa.delta_in[i].begin();
00145         
00146         j = 1;
00147         for (it_int++; it_int != Sa.delta_in[i].end(); it_int++)
00148         {
00149           
00150           
00151           k = *(--it_int);
00152           it_int++;
00153           
00154           if (Sa.transitions_labels[*it_int] != Sa.transitions_labels[k])
00155             
00156             if (j == 1)
00157               delta_det_in_A[i].push_back(k);
00158           
00159             else
00160               
00161               j = 1;
00162           
00163           else
00164             j++;
00165         }
00166         
00167         if (j == 1)
00168         {
00169           delta_det_in_A[i].push_back(*(--it_int));
00170           it_int++;
00171         }
00172       }
00173       if ((Sa.delta_out[i]).size() > 0)
00174       {
00175         it_int = Sa.delta_out[i].begin();
00176         
00177         j = 1;
00178         for (it_int++; it_int != Sa.delta_out[i].end(); it_int++)
00179         {
00180           
00181           
00182           k = *(--it_int);
00183           it_int++;
00184           
00185           if (Sa.transitions_labels[*it_int] != Sa.transitions_labels[k])
00186             
00187             if (j == 1)
00188               delta_det_out_A[i].push_back(k);
00189           
00190             else
00191               
00192               j = 1;
00193           
00194           else
00195             j++;
00196         }
00197         
00198         if (j == 1)
00199         {
00200           delta_det_out_A[i].push_back(*(--it_int));
00201           ++it_int;
00202         }
00203       }
00204     }
00205 
00206     
00207     for (i = 0; i < static_cast<int>(a.states().size()); i++)
00208     {
00209       if ((Sb.delta_in[i]).size() > 0)
00210       {
00211         it_int = Sb.delta_in[i].begin();
00212         
00213         j = 1;
00214         for (it_int++; it_int != Sb.delta_in[i].end(); it_int++)
00215         {
00216           
00217           
00218           k = *(--it_int);
00219           it_int++;
00220           
00221           if (Sb.transitions_labels[*it_int] != Sb.transitions_labels[k])
00222             
00223             if (j == 1)
00224               delta_det_in_B[i].push_back(k);
00225           
00226             else
00227               
00228               j = 1;
00229           
00230           else
00231             j++;
00232         }
00233         
00234         if (j == 1)
00235         {
00236           delta_det_in_B[i].push_back(*(--it_int));
00237           ++it_int;
00238         }
00239       }
00240       if ((Sb.delta_out[i]).size() > 0)
00241       {
00242         it_int = Sb.delta_out[i].begin();
00243         
00244         j = 1;
00245         for (it_int++; it_int != Sb.delta_out[i].end(); it_int++)
00246         {
00247           
00248           
00249           k = *(--it_int);
00250           it_int++;
00251           
00252           if (Sb.transitions_labels[*it_int] != Sb.transitions_labels[k])
00253             
00254             if (j == 1)
00255               delta_det_out_B[i].push_back(k);
00256           
00257             else
00258               
00259               j = 1;
00260           
00261           else
00262             j++;
00263         }
00264         
00265         if (j == 1)
00266         {
00267           delta_det_out_B[i].push_back(*(--it_int));
00268           it_int++;
00269         }
00270       }
00271     }
00272 
00273     
00274     
00275     for (i = 0; i < static_cast<int>(a.states().size()); i++)
00276     {
00277       
00278       
00279       
00280       std::vector<int> all_transitions_lex((Sa.delta_in[i]).size() +
00281                                            (Sa.delta_out[i]).size() + 1);
00282 
00283       
00284       for (it_int = Sa.delta_in[i].begin();
00285            it_int != Sa.delta_in[i].end(); ++it_int)
00286         all_transitions_lex.push_back(Sa.transitions_labels[*it_int]);
00287 
00288       all_transitions_lex.push_back(-1);
00289       
00290       for (it_int = Sa.delta_out[i].begin();
00291            it_int != Sa.delta_out[i].end(); ++it_int)
00292         all_transitions_lex.push_back(Sa.transitions_labels[*it_int]);
00293 
00294       
00295       
00296       if (a.is_initial(Sa.states[i]))
00297         T_aux = T_I->insert(all_transitions_lex);
00298       else
00299         if (a.is_final(Sa.states[i]))
00300           T_aux = T_T->insert(all_transitions_lex);
00301         else
00302           T_aux = T_Q_IT->insert(all_transitions_lex);
00303 
00304       
00305       if ((T_aux->A).size() == 0)
00306       {
00307         
00308         C.push_front(T_aux);
00309 
00310         
00311         T_aux->L = C.begin();
00312       }
00313 
00314       
00315       (T_aux->A).push_front(i);
00316       
00317       class_state_A[i] = T_aux;
00318       
00319       T_L_A[i] = (T_aux->A).begin();
00320     }
00321 
00322 
00323     
00324     
00325     for (i = 0; (i < static_cast<int>(b.states().size())) && iso; i++)
00326     {
00327       
00328       
00329       
00330       std::vector<int> all_transitions_lex((Sb.delta_in[i]).size() +
00331                                            (Sb.delta_out[i]).size() + 1);
00332       
00333       for (it_int = Sb.delta_in[i].begin();
00334            it_int != Sb.delta_in[i].end(); ++it_int)
00335         all_transitions_lex.push_back(Sb.transitions_labels[*it_int]);
00336 
00337       all_transitions_lex.push_back(-1);
00338       
00339       for (it_int = Sb.delta_out[i].begin();
00340            it_int != Sb.delta_out[i].end(); ++it_int)
00341         all_transitions_lex.push_back(Sb.transitions_labels[*it_int]);
00342 
00343       
00344       
00345       if (b.is_initial(Sa.states[i]))
00346         T_aux = T_I->insert(all_transitions_lex);
00347       else
00348         if (b.is_final(Sa.states[i]))
00349           T_aux = T_T->insert(all_transitions_lex);
00350         else
00351           T_aux = T_Q_IT->insert(all_transitions_lex);
00352 
00353       
00354       
00355       if ((T_aux->A).size() == (T_aux->B).size())
00356         iso = false;
00357       else
00358       {
00359         
00360         (T_aux->B).push_front(i);
00361         
00362         class_state_B[i] = T_aux;
00363         
00364         T_L_B[i] = (T_aux->B).begin();
00365       }
00366     }
00367 
00368     
00369     if (!iso)
00370       return false;
00371 
00372     for (i = 0; i < static_cast<int>(a.states().size()); i++)
00373       perm_A[i] = perm_B[i] = -1;
00374 
00375 
00376     
00377     
00378     
00379     
00380     
00381 
00382     std::list<Trie*>::iterator itr_C;
00383 
00384     itr_C = C.begin();
00385 
00386     while ((itr_C != C.end()) && iso)
00387     {
00388       
00389       
00390       if (((*itr_C)->A).size() != ((*itr_C)->B).size())
00391       {
00392         iso = false;
00393         itr_C++;
00394       }
00395       else
00396         
00397         if (((*itr_C)->A).size() == 1)
00398         {
00399           
00400           
00401           U.push_front(k = (*(((*itr_C)->A).begin())));
00402           perm_A[k] = l = *(((*itr_C)->B).begin());
00403           perm_B[l] = k;
00404 
00405           
00406           ((*itr_C)->A).erase(((*itr_C)->A).begin());
00407           ((*itr_C)->B).erase(((*itr_C)->B).begin());
00408           
00409           itr_C = C.erase(itr_C);
00410         }
00411         else
00412           itr_C++;
00413     }
00414 
00415     
00416     if (!iso)
00417       return false;
00418 
00419     
00420     
00421     
00422     
00423     
00424     while (!U.empty() && iso)
00425     {
00426       
00427       
00428 
00429       
00430       j = perm_A[i = U.front()];
00431       U.pop_front();
00432 
00433       
00434 
00435       
00436       
00437       
00438 
00439       
00440       it_int = delta_det_in_A[i].begin();
00441       it_int_aux = delta_det_in_B[j].begin();
00442       for (; it_int != delta_det_in_A[i].end() and iso; ++it_int, ++it_int_aux)
00443       {
00444 
00445         
00446         
00447         k = Sa.origins_transitions[*it_int];
00448         l = Sb.origins_transitions[*it_int_aux];
00449 
00450         
00451         if (perm_A[k] >= 0)
00452         {
00453           
00454           
00455           if (perm_A[k] != l)
00456             iso = false;
00457         }
00458         else
00459           
00460           
00461           if (perm_B[l] != -1)
00462             iso = false;
00463         
00464           else
00465             
00466             if (class_state_A[k] != class_state_B[l])
00467               iso = false;
00468         
00469         
00470             else
00471             {
00472               perm_A[perm_B[l] = k] = l;
00473               
00474               
00475               (class_state_A[k]->A).erase(T_L_A[k]);
00476               (class_state_B[l]->B).erase(T_L_B[l]);
00477               U.push_front(k);
00478               if ((class_state_A[k]->A).size() == 1)
00479               {
00480                 
00481                 
00482                 
00483                 
00484                 
00485                 
00486 
00487                 T_aux = class_state_A[k];
00488                 k = (T_aux->A).front();
00489                 l = (T_aux->B).front();
00490                 perm_A[perm_B[l] = k] = l;
00491 
00492                 U.push_front(k);
00493 
00494                 
00495                 C.erase(T_aux->L);
00496 
00497               }
00498             }
00499       }
00500 
00501 
00502       
00503       it_int = delta_det_out_A[i].begin();
00504       it_int_aux = delta_det_out_B[j].begin();
00505       for (; it_int != delta_det_out_A[i].end() && iso; ++it_int, ++it_int_aux)
00506       {
00507 
00508         
00509         
00510         k = Sa.aims_transitions[*it_int];
00511         l = Sb.aims_transitions[*it_int_aux];
00512 
00513         
00514         if (perm_A[k] >= 0)
00515         {
00516           
00517           
00518           if (perm_A[k] != l)
00519             iso = false;
00520         }
00521         else
00522           
00523           if (perm_B[l] != -1)
00524             iso = false;
00525         
00526           else
00527             
00528             if (class_state_A[k] != class_state_B[l])
00529               iso = false;
00530         
00531             else
00532             {
00533               perm_A[perm_B[l] = k] = l;
00534               
00535               
00536               (class_state_A[k]->A).erase(T_L_A[k]);
00537               (class_state_B[l]->B).erase(T_L_B[l]);
00538               U.push_front(k);
00539 
00540               if ((class_state_A[k]->A).size() == 1)
00541               {
00542                 
00543                 
00544                 
00545                 
00546                 
00547                 
00548 
00549                 T_aux = class_state_A[k];
00550                 k = (T_aux->A).front();
00551                 l = (T_aux->B).front();
00552                 perm_A[perm_B[l] = k] = l;
00553 
00554                 U.push_front(k);
00555 
00556                 
00557                 C.erase(T_aux->L);
00558 
00559               }
00560             }
00561       }
00562 
00563     }
00564 
00565     
00566     if (!iso)
00567       return false;
00568 
00569 
00570     
00571     
00572 
00573     
00574     l = 0;
00575     for (itr_C = C.begin(); itr_C != C.end(); ++itr_C)
00576       l += (*itr_C)->A.size();
00577 
00578     
00579     
00580     
00581     
00582     
00583     std::vector<int> C_A(l);
00584     std::vector<int> C_B(l + 2 * C.size());
00585     
00586     
00587     std::vector<int> current(l);
00588 
00589 
00590     
00591     
00592     std::vector<int> correspondence_transitions(a.states().size());
00593 
00594     for (i = 0; i < static_cast<int>(a.states().size()); ++i)
00595       correspondence_transitions[i] = 0;
00596 
00597     
00598     
00599     
00600     i = j = 0;
00601     for (itr_C = C.begin(); itr_C != C.end(); itr_C++)
00602     {
00603       it_int = ((*itr_C)->A).begin();
00604       it_int_B = ((*itr_C)->B).begin();
00605       C_A[i] = *it_int;
00606       C_B[j] = *it_int_B;
00607       current[i++] = j++;
00608       for (it_int++, it_int_B++; it_int != ((*itr_C)->A).end();
00609            it_int++, it_int_B++)
00610       {
00611         C_A[i] = *it_int;
00612         C_B[j++] = *it_int_B;
00613         current[i] = current[i - 1];
00614         i++;
00615       }
00616       
00617       C_B[j++] = -1;
00618       
00619       C_B[j++] = current[i - 1];
00620     }
00621 
00622     
00623 
00624     i = 0;
00625 
00626     
00627     
00628     while (iso && (i < static_cast<int>(C_A.size())))
00629     {
00630       
00631       for (j = current[i]; (C_B[j] != -1) && (perm_B[C_B[j]] >= 0); j++)
00632         ;
00633 
00634       
00635       if (C_B[j] == -1)
00636       {
00637         
00638         
00639         if (i == 0)
00640           iso = false;
00641         else
00642         {
00643           
00644           
00645           current[i] = C_B[j + 1];
00646           
00647           
00648           i--;
00649           perm_B[perm_A[C_A[i]]] = -1;
00650           perm_A[C_A[i]] = -1;
00651           current[i]++;
00652         }
00653       }
00654       
00655       else
00656       {
00657 
00658         current[i] = j;
00659         perm_A[C_A[i]] = C_B[j];
00660         perm_B[C_B[j]] = C_A[i];
00661 
00662         
00663         
00664 
00665         std::list<int>::iterator int_itr_B;
00666 
00667         it_int = Sa.delta_in[C_A[i]].begin();
00668         it_int_B = Sb.delta_in[C_B[j]].begin();
00669         bool b = true;
00670 
00671         
00672         
00673         while ((it_int != Sa.delta_in[C_A[i]].end()) && b)
00674         {
00675           
00676           
00677           
00678           
00679           k = 0;
00680           for (it_int_aux = it_int;
00681                (it_int_aux != Sa.delta_in[C_A[i]].end()) &&
00682                  (Sa.transitions_labels[*it_int_aux] ==
00683                   Sa.transitions_labels[*it_int]);
00684                it_int_aux++, k++)
00685             
00686             if (perm_A[Sa.origins_transitions[*it_int_aux]] >= 0)
00687               correspondence_transitions[Sa.origins_transitions[*it_int_aux]]++;
00688 
00689           
00690 
00691           
00692           
00693           for (; (k > 0) && b; it_int_B++, k--)
00694             
00695             if (perm_B[Sb.origins_transitions[*it_int_B]] >= 0)
00696               
00697               
00698               if (correspondence_transitions[perm_B[Sb.origins_transitions[*it_int_B]]] == 0)
00699                 
00700                 b = false;
00701               else
00702                 correspondence_transitions[perm_B[Sb.origins_transitions[*it_int_B]]]--;
00703 
00704           
00705           
00706           
00707           
00708           
00709 
00710           for (; it_int != it_int_aux; it_int++)
00711           {
00712             if (perm_A[Sa.origins_transitions[*it_int]] >= 0)
00713               if (correspondence_transitions[Sa.origins_transitions[*it_int]] != 0)
00714                 b = false;
00715             
00716             correspondence_transitions[Sa.origins_transitions[*it_int]] = 0;
00717           }
00718 
00719         } 
00720 
00721         
00722         if (b)
00723         {
00724           
00725           
00726 
00727           std::list<int>::iterator int_itr_B;
00728 
00729           it_int = Sa.delta_out[C_A[i]].begin();
00730           it_int_B = Sb.delta_out[C_B[j]].begin();
00731 
00732           
00733           
00734           while ((it_int != Sa.delta_out[C_A[i]].end()) && b)
00735           {
00736             
00737             
00738             
00739             
00740             k = 0;
00741             for (it_int_aux = it_int;
00742                  (it_int_aux != Sa.delta_out[C_A[i]].end()) &&
00743                    (Sa.transitions_labels[*it_int_aux] ==
00744                     Sa.transitions_labels[*it_int]);
00745                  it_int_aux++, k++)
00746               
00747               if (perm_A[Sa.aims_transitions[*it_int_aux]] >= 0)
00748                 correspondence_transitions[Sa.aims_transitions[*it_int_aux]]++;
00749 
00750             
00751 
00752             
00753             
00754             for (; (k > 0) && b; it_int_B++, k--)
00755               
00756               if (perm_B[Sb.aims_transitions[*it_int_B]] >= 0)
00757                 
00758                 
00759                 if (correspondence_transitions[perm_B[Sb.aims_transitions[*it_int_B]]] == 0)
00760                   
00761                   
00762                   b = false;
00763                 else
00764                   correspondence_transitions[perm_B[Sb.aims_transitions[*it_int_B]]]--;
00765 
00766             
00767             
00768             
00769             
00770             
00771             
00772 
00773             for (; it_int != it_int_aux; it_int++)
00774             {
00775               if (perm_A[Sa.aims_transitions[*it_int]] >= 0)
00776                 if (correspondence_transitions[Sa.aims_transitions[*it_int]] != 0)
00777                   b = false;
00778               
00779               correspondence_transitions[Sa.aims_transitions[*it_int]] = 0;
00780             }
00781 
00782           } 
00783 
00784         } 
00785 
00786         
00787         if (b)
00788           
00789           i++;
00790         
00791         else
00792         {
00793           
00794           perm_B[perm_A[C_A[i]]] = -1;
00795           perm_A[C_A[i]] = -1;
00796           current[i]++;
00797         }
00798 
00799       } 
00800 
00801     } 
00802 
00803     return (iso);
00804 
00805   } 
00806 
00807 } 
00808 
00809 #endif // ! VCSN_ALGORITHMS_ISOMORPH_HXX