Home | History | Annotate | Download | only in grxmlcompile
      1 /* FILE:		sub_min.cpp
      2  *  DATE MODIFIED:	31-Aug-07
      3  *  DESCRIPTION:	Part of the  SREC graph compiler project source files.
      4  *
      5  *  Copyright 2007, 2008 Nuance Communciations, Inc.                               *
      6  *                                                                           *
      7  *  Licensed under the Apache License, Version 2.0 (the 'License');          *
      8  *  you may not use this file except in compliance with the License.         *
      9  *                                                                           *
     10  *  You may obtain a copy of the License at                                  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0                           *
     12  *                                                                           *
     13  *  Unless required by applicable law or agreed to in writing, software      *
     14  *  distributed under the License is distributed on an 'AS IS' BASIS,        *
     15  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
     16  *  See the License for the specific language governing permissions and      *
     17  *  limitations under the License.                                           *
     18  *                                                                           *
     19  *---------------------------------------------------------------------------*/
     20 
     21 #include <iostream>
     22 #include <string>
     23 #include <assert.h>
     24 #include <cstdio>
     25 
     26 #include "sub_grph.h"
     27 
     28 #define SYMBOL_COMPARE(x,y) (arc[x]->CompareSymbol(arc[y]))
     29 #define COMPARE(x,y) (arc[x]->Compare(arc[y]))
     30 
     31 //  Minimization to facilitate moving output symbols - mainly for phoneme networks
     32 //      Check partial merge
     33 //      Move the output symbol if only one node
     34 
     35 /*
     36 static int checkEntry (int *itemList, int count, int item);
     37 
     38 static int checkEntry (int *itemList, int count, int item)
     39 {
     40     for (int ii= 0; ii < count; ii++)
     41         if (item == itemList[ii])
     42             return ii;
     43     return -1;
     44 }
     45 */
     46 
     47 void SubGraph::ViewNode (int currId)
     48 {
     49     int  rix;
     50 
     51     printf ("Node: %d\n", currId);
     52     rix= FindFromIndex (currId);
     53     if (rix < 0)
     54         return;
     55     while (rix < numArc && arc[forwardList[rix]]->GetFromId() == currId) {
     56         arc[forwardList[rix]]->Print();
     57         rix++;
     58     }
     59     return;
     60 }
     61 
     62 
     63 bool SubGraph::EquivalenceTestForward (int firstId, int secondId, int *equivMap)
     64 {
     65     int  fix, six, fnxt, snxt, tof, tos, count;
     66 
     67     assert (firstId != secondId);
     68     fix= FindFromIndex (firstId);
     69     six= FindFromIndex (secondId);
     70     if (fix < 0 || six < 0)
     71         return false;
     72 
     73     count= 0;
     74     do {
     75 
     76         //  Move to next valid transitions
     77         while (fix < numArc && arc[forwardList[fix]]->GetFromId() == firstId
     78             && arc[forwardList[fix]]->GetToId() == DISCARD_LABEL)
     79             fix++;
     80         if (fix < numArc && arc[forwardList[fix]]->GetFromId() == firstId)
     81             fnxt= arc[forwardList[fix]]->GetFromId();
     82         else
     83             fnxt= -1;
     84 
     85         while (six < numArc && arc[forwardList[six]]->GetFromId() == secondId
     86             && arc[forwardList[six]]->GetToId() == DISCARD_LABEL)
     87             six++;
     88         if (six < numArc && arc[forwardList[six]]->GetFromId() == secondId)
     89             snxt= arc[forwardList[six]]->GetFromId();
     90         else
     91             snxt= -1;
     92 
     93         if (fnxt != firstId && snxt != secondId)
     94             return true;
     95         else if (fnxt != firstId || snxt != secondId)
     96             return false;
     97 
     98 	tos= arc[forwardList[six]]->GetToId();
     99 	tof= arc[forwardList[fix]]->GetToId();
    100         // printf ("Debug inner %d %d, %d %d\n", tof, tos, equivMap[tof], equivMap[tos]);
    101 	// if (tof >= 0)		bogus assert
    102 	    // assert (tof == equivMap[tof]);
    103 	// if (tos >= 0)
    104 	    // assert (tos == equivMap[tos]);
    105 
    106         //  Test
    107         if (!arc[forwardList[fix]]->HasSameLabels (arc[forwardList[six]])
    108 	    || tos != tof)
    109             return false;
    110 	count++;
    111 
    112         fix++;
    113         six++;
    114 
    115     }  while (fnxt >= 0 && snxt >= 0);
    116 
    117     return false;
    118 }
    119 
    120 void SubGraph::IdentifyEquivalence (int *depthMap, int *equivMap)
    121 {
    122     int ii, jj, dd, maxDepth, count, itCnt;
    123 
    124     maxDepth= 0;
    125     for (ii= 0; ii < numVertex; ii++) {
    126         if (maxDepth < depthMap[ii])
    127             maxDepth= depthMap[ii];
    128     }
    129 
    130     itCnt= 0;
    131     do {
    132         count= 0;
    133         for (dd= 0; dd <= maxDepth; dd++)
    134             for (ii= 0; ii < numVertex; ii++)
    135                 if (depthMap[ii] == dd && ii == equivMap[ii]) {
    136                     CheckForChangeAndResort (ii, equivMap);
    137                     for (jj= ii+1; jj < numVertex; jj++)
    138                         if (depthMap[jj] == dd && jj == equivMap[jj]) {
    139                             // Equivalence test
    140                             CheckForChangeAndResort (jj, equivMap);
    141                             // printf ("Try %d %d, ", ii, jj);
    142                             if (EquivalenceTestForward (ii, jj, equivMap)) {
    143                                 equivMap[jj]= ii;
    144                                 // printf ("Merged %d %d\n", ii, jj);
    145                                 count++;
    146                             }
    147                         }
    148                 }
    149 
    150         itCnt++;
    151         // printf ("Total %d mergers\n", count);
    152     } while (count > 0 && itCnt < MAXITS);
    153 
    154     return;
    155 }
    156 
    157 void SubGraph::CheckForChangeAndResort (int currId, int *mapList)
    158 {
    159     int  rix, rixBegin, nextId;
    160     bool needSort;
    161 
    162     needSort= false;
    163     rixBegin= rix= FindFromIndex (currId);
    164     if (rix < 0)
    165         return;
    166     while (rix < numArc && arc[forwardList[rix]]->GetFromId() == currId) {
    167         nextId= arc[forwardList[rix]]->GetToId();
    168         if (nextId >= 0 && mapList[nextId] != nextId) {
    169             needSort= true;
    170             arc[forwardList[rix]]->AssignToId(mapList[nextId]);
    171         }
    172         rix++;
    173     }
    174 
    175     //  Resort
    176     if (needSort)
    177         RemoveDuplicatesAtNode (rixBegin, rix);
    178 
    179     return;
    180 }
    181 
    182 void SubGraph::DeterminizeAtVertex (int baseId, DetCache *cache)
    183 {
    184     int  fix, six, firstId, secondId, vertEnd;
    185 
    186     fix= FindFromIndex (baseId);
    187     if (fix < 0)
    188         return;
    189 
    190     // Remove duplicates
    191     vertEnd= fix;
    192     six= -1;
    193     while (vertEnd < sortNum && arc[forwardList[vertEnd]]->GetFromId() == baseId) {
    194         vertEnd++;
    195     }
    196     vertEnd++;
    197 
    198     //  Iteration over first node
    199     firstId= -1;
    200     while (fix < sortNum && arc[forwardList[fix]]->GetFromId() == baseId) {
    201 
    202         //  Iterator for firstId
    203         while (fix < sortNum && arc[forwardList[fix]]->GetFromId() == baseId
    204             && (arc[forwardList[fix]]->GetToId() == firstId
    205 		    || arc[forwardList[fix]]->GetInput() == TERMINAL_LABEL
    206 		    || arc[forwardList[fix]]->GetInput() == DISCARD_LABEL))
    207             fix++;
    208 
    209 	// Terminal Condition
    210 	if (fix >= sortNum || arc[forwardList[fix]]->GetFromId() != baseId)
    211 	    break;
    212 	else
    213 	    firstId= arc[forwardList[fix]]->GetToId();
    214 
    215         //  Iteration over second node
    216 	six= fix;
    217         secondId= firstId;
    218         while (six < sortNum && arc[forwardList[six]]->GetFromId() == baseId) {
    219 
    220 	        //  Iterator for secondId
    221             while (six < sortNum && arc[forwardList[six]]->GetFromId() == baseId
    222                 && (arc[forwardList[six]]->GetToId() == secondId
    223 		        || arc[forwardList[six]]->GetInput() == TERMINAL_LABEL
    224 		        || arc[forwardList[six]]->GetInput() == DISCARD_LABEL))
    225 		        six++;
    226 
    227 	        //  Terminal condition
    228 	        if (six >= sortNum || arc[forwardList[six]]->GetFromId() != baseId)
    229 		    break;
    230 	        else
    231 		    secondId= arc[forwardList[six]]->GetToId();
    232 
    233             //  Now we have both Ids worked out
    234 	        assert (firstId >= 0);
    235 	        assert (secondId >= 0);
    236                 assert (arc[forwardList[fix]]->GetInput() != DISCARD_LABEL);
    237                 assert (arc[forwardList[six]]->GetInput() != DISCARD_LABEL);
    238 
    239             if (PairwiseDeterminize (baseId, firstId, fix, secondId, six, cache) > 0) {
    240                 SortLanguageAtSortIndices (fix, vertEnd);
    241 
    242                 //  Are we done with the first node?
    243                 while (fix < sortNum && arc[forwardList[fix]]->GetFromId() == baseId
    244                    && arc[forwardList[fix]]->GetInput() == DISCARD_LABEL)
    245                     fix++;
    246 
    247 	            //  Terminal condition
    248 	            if (fix >= sortNum || arc[forwardList[fix]]->GetFromId() != baseId
    249                  || arc[forwardList[fix]]->GetToId() != firstId)
    250 		            break;
    251             }
    252         }
    253     }
    254     return;
    255 }
    256 
    257 int SubGraph::PairwiseDeterminize (int baseId, int firstId, int fixStart, int secondId,
    258                                    int sixStart, DetCache *cache)
    259 {
    260     int  fix, six, fmiss, smiss, nmatch, symTst, newId;
    261     bool isCached;
    262 
    263     fix= fixStart;
    264     six= sixStart;
    265 
    266     assert (arc[forwardList[fix]]->GetInput() != DISCARD_LABEL);
    267     assert (arc[forwardList[six]]->GetInput() != DISCARD_LABEL);
    268 
    269     //  Count
    270     isCached= false;
    271     fmiss= smiss= nmatch= 0;
    272     newId= -1;
    273     while (six < sortNum && fix < sortNum) {
    274 
    275         assert (arc[forwardList[fix]]->GetInput() != DISCARD_LABEL);
    276         assert (arc[forwardList[six]]->GetInput() != DISCARD_LABEL);
    277 
    278         symTst= SYMBOL_COMPARE (forwardList[fix], forwardList[six]);
    279         if (symTst == 0) {
    280             if (newId == -1) {
    281                 newId= cache->QueryEntry (firstId, secondId);
    282 		if (newId < 0)
    283                     newId= NewVertexId ();
    284                 else
    285                     isCached= true;
    286 		// printf ("Forming %d with %d and %d at %d\n", newId, firstId, secondId, baseId);
    287             }
    288 
    289             //  Assign second to new Vertex
    290             arc[forwardList[six]]->AssignToId (newId);
    291 
    292             //  Assign first to DISCARD Index
    293             arc[forwardList[fix]]->AssignInput (DISCARD_LABEL);
    294 
    295             //  Increment to next
    296             do {
    297                 fix++;
    298             } while (fix < sortNum && arc[forwardList[fix]]->GetInput() == DISCARD_LABEL);
    299             if (fix >= sortNum || arc[forwardList[fix]]->GetFromId() != baseId
    300                 || arc[forwardList[fix]]->GetToId() != firstId)
    301                 fix= sortNum;
    302 
    303             do {
    304                 six++;
    305             } while (six < sortNum && arc[forwardList[six]]->GetInput() == DISCARD_LABEL);
    306             if (six >= sortNum || arc[forwardList[six]]->GetFromId() != baseId
    307                 || arc[forwardList[six]]->GetToId() != secondId)
    308                 six= sortNum;
    309 
    310             nmatch++;
    311         }
    312         else if (symTst < 0) {
    313             do {
    314                 fix++;
    315             } while (fix < sortNum && arc[forwardList[fix]]->GetInput() == DISCARD_LABEL);
    316             if (fix >= sortNum || arc[forwardList[fix]]->GetFromId() != baseId
    317                 || arc[forwardList[fix]]->GetToId() != firstId)
    318                 fix= sortNum;
    319             fmiss++;
    320         }
    321         else if (symTst > 0) {
    322             do {
    323                 six++;
    324             } while (six < sortNum && arc[forwardList[six]]->GetInput() == DISCARD_LABEL);
    325             if (six >= sortNum || arc[forwardList[six]]->GetFromId() != baseId
    326                 || arc[forwardList[six]]->GetToId() != secondId)
    327                 six= sortNum;
    328             smiss++;
    329         }
    330     }
    331 
    332     // SortLanguageAtSortIndices (fixStart, fix);
    333 
    334     if (newId >= 0) {
    335         if (isCached == false) {
    336             // numLast= numArc;
    337             MergeVertices (newId, firstId, secondId);
    338             cache->AddEntry (newId, firstId, secondId);
    339             // UpdateVisitationCache (numLast);
    340         }
    341         assert (nmatch > 0);
    342     }
    343 
    344     //  Update fan-in count
    345     if (nmatch > 0) {
    346         // printf ("Merging %d %d to create %d\n", firstId, secondId, newId);
    347         for (int ii= 0; ii < nmatch; ii++) {
    348             // IncNodeProperty (newId);
    349             IncVisitationCache (newId);
    350             DecVisitationCache (firstId);
    351             DecVisitationCache (secondId);
    352         }
    353     }
    354     return nmatch;
    355 }
    356 
    357 void SubGraph::MergeVertices (int newId, int firstId, int secondId)
    358 {
    359     int fix, six, symTst, numStart;
    360     NUANArc *arcOne;
    361 
    362     numStart= numArc;
    363     fix= FindFromIndex (firstId);
    364     six= FindFromIndex (secondId);
    365     if (fix < 0 || six < 0) {
    366         if (fix >= 0)
    367             while (fix < sortNum && arc[forwardList[fix]]->GetFromId() == firstId) {
    368                 if (arc[forwardList[fix]]->GetInput() != DISCARD_LABEL)
    369                     InheritArc (arc[forwardList[fix]], newId);
    370                 fix++;
    371             }
    372         else if (six >= 0)
    373             while (six < sortNum && arc[forwardList[six]]->GetFromId() == secondId) {
    374                 if (arc[forwardList[six]]->GetInput() != DISCARD_LABEL)
    375                     InheritArc (arc[forwardList[six]], newId);
    376                 six++;
    377             }
    378     }
    379     else {
    380         while (six < sortNum && fix < sortNum) {
    381 
    382             symTst= SYMBOL_COMPARE (forwardList[fix], forwardList[six]);
    383 
    384             if (symTst == 0) {
    385                 if (arc[forwardList[fix]]->GetToId() == firstId
    386                  && arc[forwardList[six]]->GetToId() == secondId) {
    387                     arcOne= InheritArc (arc[forwardList[fix]], newId);
    388                     arcOne->AssignToId (newId);
    389                 }
    390                 else if (arc[forwardList[fix]]->GetToId()
    391                  == arc[forwardList[six]]->GetToId()) {
    392                     InheritArc (arc[forwardList[fix]], newId);
    393 		}
    394                 else {
    395                     InheritArc (arc[forwardList[fix]], newId);
    396                     InheritArc (arc[forwardList[six]], newId);
    397                 }
    398 
    399                 //  Increment to next
    400                 do {
    401                     fix++;
    402                 } while (fix < sortNum && arc[forwardList[fix]]->GetInput() == DISCARD_LABEL);
    403                 if (fix >= sortNum || arc[forwardList[fix]]->GetFromId() != firstId
    404                     || arc[forwardList[fix]]->GetFromId() != firstId)
    405                     fix= sortNum;
    406 
    407                 do {
    408                     six++;
    409                 } while (six < sortNum && arc[forwardList[six]]->GetInput() == DISCARD_LABEL);
    410                 if (six >= sortNum || arc[forwardList[six]]->GetFromId() != secondId)
    411                     six= sortNum;
    412             }
    413             else if (symTst < 0) {
    414                 InheritArc (arc[forwardList[fix]], newId);
    415                 do {
    416                     fix++;
    417                 } while (fix < sortNum && arc[forwardList[fix]]->GetInput() == DISCARD_LABEL);
    418                 if (fix >= sortNum || arc[forwardList[fix]]->GetFromId() != firstId
    419                     || arc[forwardList[fix]]->GetFromId() != firstId)
    420                     fix= sortNum;
    421             }
    422             else if (symTst > 0) {
    423                 InheritArc (arc[forwardList[six]], newId);
    424                 do {
    425                     six++;
    426                 } while (six < sortNum && arc[forwardList[six]]->GetInput() == DISCARD_LABEL);
    427                 if (six >= sortNum || arc[forwardList[six]]->GetFromId() != secondId
    428                     || arc[forwardList[six]]->GetFromId() != secondId)
    429                     six= sortNum;
    430             }
    431         }
    432 
    433         while (fix < sortNum && arc[forwardList[fix]]->GetFromId() == firstId) {
    434             if (arc[forwardList[fix]]->GetInput() != DISCARD_LABEL)
    435                 InheritArc (arc[forwardList[fix]], newId);
    436             fix++;
    437         }
    438 
    439         while (six < sortNum && arc[forwardList[six]]->GetFromId() == secondId) {
    440             if (arc[forwardList[six]]->GetInput() != DISCARD_LABEL)
    441                 InheritArc (arc[forwardList[six]], newId);
    442             six++;
    443         }
    444     }
    445 
    446     //  Update the sort list
    447     UpdateSortForLanguage ();
    448     // RemoveDuplicatesAtNode (numStart, numArc);
    449     // ViewNode (newId);
    450     assert (CheckSort());
    451 
    452     // printf ("Merging %d %d to create %d\n", firstId, secondId, newId);
    453 
    454     return;
    455 }
    456 
    457 void SubGraph::SetupVisitationCache ()
    458 {
    459     int ii;
    460 
    461     CreateNodeProperty ();
    462     for (ii= 0; ii < numArc; ii++)
    463         if (arc[ii]->GetInput() != DISCARD_LABEL && arc[ii]->GetToId() >= 0)
    464             IncNodeProperty (arc[ii]->GetToId());
    465     return;
    466 }
    467 
    468 void SubGraph::ClearVisitationCache ()
    469 {
    470     DeleteNodeProperty ();
    471     return;
    472 }
    473 
    474 void SubGraph::UpdateVisitationCache (int startNo)
    475 {
    476     int ii;
    477 
    478     for (ii= startNo; ii < numArc; ii++)
    479         if (arc[ii]->GetInput() != DISCARD_LABEL && arc[ii]->GetToId() >= 0) {
    480             IncNodeProperty (arc[ii]->GetToId());
    481             // std::cout << " (" << arc[ii]->GetToId() << " " << QueryNodeProperty (arc[ii]->GetToId()) << ") ";
    482         }
    483     // std::cout << std::endl;
    484     return;
    485 }
    486 
    487 void SubGraph::DecVisitationCache (int currId)
    488 {
    489     int rix;
    490 
    491     DecNodeProperty (currId);
    492     // std::cout << " [" << currId << " " << QueryNodeProperty (currId) << "] ";
    493     if (QueryNodeProperty (currId) <= 0) {
    494         // std::cout << " [" << currId << "] ";
    495         rix= FindFromIndex (currId);
    496         if (rix < 0)
    497             return;
    498         while (rix < sortNum && arc[forwardList[rix]]->GetFromId() == currId) {
    499             if (arc[forwardList[rix]]->GetInput() != DISCARD_LABEL
    500                 && arc[forwardList[rix]]->GetToId() >= 0) {
    501                 if (arc[forwardList[rix]]->GetFromId() == arc[forwardList[rix]]->GetToId())
    502                     DecNodeProperty (currId);
    503                 else if (QueryNodeProperty (arc[forwardList[rix]]->GetToId()) > 0)
    504                     DecVisitationCache (arc[forwardList[rix]]->GetToId());
    505             }
    506             rix++;
    507         }
    508     }
    509     return;
    510 }
    511 
    512 void SubGraph::IncVisitationCache (int currId)
    513 {
    514     int rix;
    515 
    516     if (QueryNodeProperty (currId) <= 0) {
    517         IncNodeProperty (currId);
    518         // std::cout << " (" << currId << ") ";
    519         rix= FindFromIndex (currId);
    520         if (rix < 0)
    521             return;
    522         while (rix < sortNum && arc[forwardList[rix]]->GetFromId() == currId) {
    523             if (arc[forwardList[rix]]->GetInput() != DISCARD_LABEL
    524                 && arc[forwardList[rix]]->GetToId() >= 0) {
    525                 // IncNodeProperty (arc[forwardList[rix]]->GetToId());
    526 		// if (currId != arc[forwardList[rix]]->GetToId())
    527                     IncVisitationCache (arc[forwardList[rix]]->GetToId());
    528             }
    529             rix++;
    530         }
    531     }
    532     else
    533         IncNodeProperty (currId);
    534     // std::cout << " (" << currId << " " << QueryNodeProperty (currId) << ") ";
    535     return;
    536 }
    537 
    538 int SubGraph::VisitationConsistencyCheck ()
    539 {
    540     int ii, failCount;
    541 
    542     int *nodeCount= new int [numVertex];
    543 
    544     UpdateVertexCount (0);
    545 
    546     // std::cout << "Count: ";
    547     for (ii= 0; ii <numVertex; ii++) {
    548         // std::cout << ii << " (" << vertexProp[ii] << ") ";
    549         nodeCount[ii]= 0;
    550     }
    551     // std::cout << std::endl;
    552     for (ii= 0; ii <numArc; ii++)
    553         if (arc[ii]->GetInput() != DISCARD_LABEL && arc[ii]->GetToId() >= 0
    554             && (vertexProp[arc[ii]->GetFromId()] > 0 || arc[ii]->GetFromId() == startId))
    555             nodeCount[arc[ii]->GetToId()]++;
    556     failCount= 0;
    557     // std::cout << "Failure list: ";
    558     for (ii= 0; ii <numVertex; ii++)
    559         if (vertexProp[ii] != nodeCount[ii]) {
    560             // std::cout << ii << " (" << vertexProp[ii] << " " << nodeCount[ii] << ") ";
    561             failCount++;
    562         }
    563     // std::cout << std::endl;
    564 
    565     // return failCount;
    566     delete [] nodeCount;
    567 
    568     return 0;
    569 }
    570