| /* FILE: sub_supp.cpp |
| * DATE MODIFIED: 31-Aug-07 |
| * DESCRIPTION: Part of the SREC graph compiler project source files. |
| * |
| * Copyright 2007, 2008 Nuance Communciations, Inc. * |
| * * |
| * Licensed under the Apache License, Version 2.0 (the 'License'); * |
| * you may not use this file except in compliance with the License. * |
| * * |
| * You may obtain a copy of the License at * |
| * http://www.apache.org/licenses/LICENSE-2.0 * |
| * * |
| * Unless required by applicable law or agreed to in writing, software * |
| * distributed under the License is distributed on an 'AS IS' BASIS, * |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * |
| * See the License for the specific language governing permissions and * |
| * limitations under the License. * |
| * * |
| *---------------------------------------------------------------------------*/ |
| |
| #include <iostream> |
| #include <string> |
| #include <assert.h> |
| #include <cstdio> |
| |
| #include "sub_grph.h" |
| |
| |
| #define ARC_COMPARE(x,y) (arc[x]->Compare(arc[y])) |
| #define ARC_COMPARE_REV(x,y) (arc[x]->CompareReverse(arc[y])) |
| #define ARC_COMPARE_MIN(x,y) (arc[x]->CompareForMin(arc[y])) |
| |
| |
| void SubGraph::SortLanguage () |
| { |
| int *sortList; |
| |
| if (numArc <= 1) { |
| sortList= new int [numArc+2]; |
| sortList[0]= 0; |
| if (forwardList) |
| delete [] forwardList; |
| forwardList= sortList; |
| sortNum= numArc; |
| return; |
| } |
| SortLanguageAtIndices (-1, -1); |
| return; |
| } |
| |
| void SubGraph::SortLanguageAtIndices (int begIx, int endIx) |
| { |
| int ii, jj, hired, retd; |
| int holdArc, *sortList; |
| |
| if (begIx < 0) |
| begIx= 0; |
| if (endIx < 0) |
| endIx= numArc; |
| |
| if (endIx <= begIx) |
| return; |
| |
| sortList= new int [numArc+2]; |
| for (ii= 0; ii < sortNum && ii < numArc; ii++) |
| sortList[ii]= forwardList[ii]; |
| for (ii= begIx; ii < endIx; ii++) |
| sortList[ii]= ii; |
| sortList--; |
| |
| /* Hiring |
| */ |
| hired= (numArc >> 1)+1; |
| while (hired-- > 1) { |
| holdArc= sortList[hired]; |
| ii= hired; |
| jj= hired << 1; |
| while (jj <= numArc) { |
| if (jj < numArc && ARC_COMPARE (sortList[jj], sortList[jj+1]) <= 0 ) |
| jj++; |
| if (ARC_COMPARE (holdArc, sortList[jj]) < 0) { |
| sortList[ii]= sortList[jj]; |
| ii= jj; |
| jj <<= 1; |
| } |
| else |
| break; |
| } |
| sortList[ii]= holdArc; |
| } |
| |
| /* Retiring |
| */ |
| retd= numArc; |
| while (retd > 0) { |
| holdArc= sortList[retd]; |
| sortList[retd]= sortList[1]; |
| if (--retd == 1) { |
| sortList[1]= holdArc; |
| break; |
| } |
| ii= 1; |
| jj= 2; |
| while (jj <= retd) { |
| if (jj < retd && ARC_COMPARE (sortList[jj], sortList[jj+1]) <= 0) |
| jj++; |
| if (ARC_COMPARE (holdArc, sortList[jj]) < 0) { |
| sortList[ii]= sortList[jj]; |
| ii= jj; |
| jj <<= 1; |
| } |
| else |
| break; |
| } |
| sortList[ii]= holdArc; |
| } |
| sortList++; |
| |
| if (forwardList) |
| delete [] forwardList; |
| forwardList= sortList; |
| sortNum= numArc; |
| |
| /* Now carry out some checks |
| */ |
| assert(CheckSort()); |
| |
| return; |
| } |
| |
| void SubGraph::SortLanguageAtSortIndices (int begIx, int endIx) |
| { |
| int ii, jj, hired, retd; |
| int holdArc, *sortList; |
| |
| if (begIx < 0) |
| begIx= 0; |
| if (endIx < 0) |
| endIx= numArc; |
| |
| if (endIx <= begIx) |
| return; |
| |
| sortList= forwardList; |
| sortList--; |
| |
| /* Hiring |
| */ |
| hired= (numArc >> 1)+1; |
| while (hired-- > 1) { |
| holdArc= sortList[hired]; |
| ii= hired; |
| jj= hired << 1; |
| while (jj <= numArc) { |
| if (jj < numArc && ARC_COMPARE (sortList[jj], sortList[jj+1]) <= 0 ) |
| jj++; |
| if (ARC_COMPARE (holdArc, sortList[jj]) < 0) { |
| sortList[ii]= sortList[jj]; |
| ii= jj; |
| jj <<= 1; |
| } |
| else |
| break; |
| } |
| sortList[ii]= holdArc; |
| } |
| |
| /* Retiring |
| */ |
| retd= numArc; |
| while (retd > 0) { |
| holdArc= sortList[retd]; |
| sortList[retd]= sortList[1]; |
| if (--retd == 1) { |
| sortList[1]= holdArc; |
| break; |
| } |
| ii= 1; |
| jj= 2; |
| while (jj <= retd) { |
| if (jj < retd && ARC_COMPARE (sortList[jj], sortList[jj+1]) <= 0) |
| jj++; |
| if (ARC_COMPARE (holdArc, sortList[jj]) < 0) { |
| sortList[ii]= sortList[jj]; |
| ii= jj; |
| jj <<= 1; |
| } |
| else |
| break; |
| } |
| sortList[ii]= holdArc; |
| } |
| sortList++; |
| |
| forwardList= sortList; |
| |
| /* Now carry out some checks |
| */ |
| assert(CheckSort()); |
| |
| return; |
| } |
| |
| int SubGraph::FindFromIndex (int element) |
| { |
| int rix, rix_low, rix_high, direction; |
| |
| rix_low= -1; |
| rix_high= sortNum; |
| while ((rix_high - rix_low) > 1) { |
| rix= (rix_high + rix_low) >> 1; |
| direction= element - arc[forwardList[rix]]->GetFromId(); |
| if (direction < 0) |
| rix_high= rix; |
| else if (direction > 0) |
| rix_low= rix; |
| else { |
| assert (arc[forwardList[rix]]->GetFromId() == element); |
| while (rix > 0 && arc[forwardList[rix-1]]->GetFromId() == element) |
| rix--; |
| assert (arc[forwardList[rix]]->GetFromId() == element); |
| assert (rix < sortNum); |
| return (rix); |
| } |
| } |
| return (-1); |
| } |
| |
| void SubGraph::SortLanguageReverse () |
| { |
| int ii, jj, hired, retd; |
| int holdArc, *sortList; |
| |
| if (numArc <= 1) { |
| sortList= new int [numArc+2]; |
| sortList[0]= 0; |
| if (backwardList) |
| delete [] backwardList; |
| backwardList= sortList; |
| sortRevNum= numArc; |
| return; |
| } |
| |
| sortList= new int [numArc+2]; |
| for (ii= 0; ii < numArc; ii++) |
| sortList[ii]= ii; |
| sortList--; |
| |
| /* Hiring |
| */ |
| hired= (numArc >> 1)+1; |
| while (hired-- > 1) { |
| holdArc= sortList[hired]; |
| ii= hired; |
| jj= hired << 1; |
| while (jj <= numArc) { |
| if (jj < numArc && ARC_COMPARE_REV (sortList[jj], sortList[jj+1]) <= 0 ) |
| jj++; |
| if (ARC_COMPARE_REV (holdArc, sortList[jj]) < 0) { |
| sortList[ii]= sortList[jj]; |
| ii= jj; |
| jj <<= 1; |
| } |
| else |
| break; |
| } |
| sortList[ii]= holdArc; |
| } |
| |
| /* Retiring |
| */ |
| retd= numArc; |
| while (retd > 0) { |
| holdArc= sortList[retd]; |
| sortList[retd]= sortList[1]; |
| if (--retd == 1) { |
| sortList[1]= holdArc; |
| break; |
| } |
| ii= 1; |
| jj= 2; |
| while (jj <= retd) { |
| if (jj < retd && ARC_COMPARE_REV (sortList[jj], sortList[jj+1]) <= 0) |
| jj++; |
| if (ARC_COMPARE_REV (holdArc, sortList[jj]) < 0) { |
| sortList[ii]= sortList[jj]; |
| ii= jj; |
| jj <<= 1; |
| } |
| else |
| break; |
| } |
| sortList[ii]= holdArc; |
| } |
| sortList++; |
| |
| if (backwardList) |
| delete [] backwardList; |
| backwardList= sortList; |
| sortRevNum= numArc; |
| |
| /* Now carry out some checks |
| */ |
| assert(CheckSortReverse()); |
| |
| return; |
| } |
| |
| int SubGraph::FindToIndex (int element) |
| { |
| int rix, rix_low, rix_high, direction; |
| |
| rix_low= -1; |
| rix_high= sortRevNum; |
| while ((rix_high - rix_low) > 1) { |
| rix= (rix_high + rix_low) >> 1; |
| direction= element - arc[backwardList[rix]]->GetToId(); |
| if (direction < 0) |
| rix_high= rix; |
| else if (direction > 0) |
| rix_low= rix; |
| else { |
| assert (arc[backwardList[rix]]->GetToId() == element); |
| while (rix > 0 && arc[backwardList[rix-1]]->GetToId() == element) |
| rix--; |
| assert (arc[backwardList[rix]]->GetToId() == element); |
| assert (rix < sortRevNum); |
| return (rix); |
| } |
| } |
| return (-1); |
| } |
| |
| void SubGraph::UpdateSortForLanguage () |
| { |
| SortLanguageAtIndices (sortNum, numArc); |
| } |
| |
| bool SubGraph::CheckSort () |
| { |
| for (int ii= 1; ii < numArc; ii++) { |
| if (ARC_COMPARE (forwardList[ii-1], forwardList[ii]) > 0) |
| return false; |
| } |
| return true; |
| } |
| |
| bool SubGraph::CheckSortReverse () |
| { |
| for (int ii= 1; ii < numArc; ii++) { |
| if (ARC_COMPARE_REV (backwardList[ii-1], backwardList[ii]) > 0) { |
| printf ("Failed at %d\n", ii); |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| void SubGraph::ClearDuplicateArcs () |
| { |
| int currId; |
| |
| SortLanguage(); |
| currId= 0; |
| for (int ii= 1; ii < numArc; ii++) { |
| if (arc[forwardList[ii]]->GetInput() != DISCARD_LABEL) |
| if (ARC_COMPARE (forwardList[currId], forwardList[ii]) == 0) |
| arc[forwardList[ii]]->AssignInput (DISCARD_LABEL); |
| else |
| currId= ii; |
| } |
| return; |
| } |
| |
| void SubGraph::RenumberNodes () |
| { |
| int ii, id, count; |
| |
| UpdateVertexCount (0); |
| if (numVertex > 0) { |
| int *mapList= new int [numVertex]; |
| for (ii= 0; ii < numVertex; ii++) |
| mapList[ii]= -1; |
| |
| for (ii= 0; ii < numArc; ii++) { |
| id= arc[ii]->GetFromId(); |
| mapList[id]= 1; |
| id= arc[ii]->GetToId(); |
| if (id >= 0) |
| mapList[id]= 1; |
| } |
| |
| count= 0; |
| for (ii= 0; ii < numVertex; ii++) |
| if (mapList[ii] > 0) { |
| mapList[ii]= count; |
| count++; |
| } |
| |
| for (ii= 0; ii < numArc; ii++) { |
| id= arc[ii]->GetFromId(); |
| arc[ii]->AssignFromId(mapList[id]); |
| id= arc[ii]->GetToId(); |
| if (id >= 0) |
| arc[ii]->AssignToId(mapList[id]); |
| } |
| startId= mapList[startId]; |
| if (lastId >= 0) |
| lastId= mapList[lastId]; |
| delete [] mapList; |
| } |
| else { |
| startId= 0; |
| lastId= -1; |
| endId= -1; |
| } |
| return; |
| } |
| |
| void SubGraph::RemoveDuplicatesAtNode (int rixBegin, int rixEnd) |
| // Works only within one node/vertex |
| { |
| int rix, lastRix; |
| bool needSort; |
| |
| SortLanguageAtSortIndices (rixBegin, rixEnd); |
| |
| // Check for duplicate transitions |
| needSort= false; |
| lastRix= rixBegin; |
| for (rix= rixBegin+1; rix < rixEnd; rix++) { |
| assert (arc[forwardList[lastRix]]->GetFromId() == arc[forwardList[rix]]->GetFromId()); |
| if (ARC_COMPARE (forwardList[lastRix], forwardList[rix]) == 0) { |
| arc[forwardList[rix]]->AssignInput (DISCARD_LABEL); |
| needSort= true; |
| } |
| else |
| lastRix= rix; |
| } |
| |
| // Resort |
| if (needSort) |
| SortLanguageAtSortIndices (rixBegin, rixEnd); |
| |
| return; |
| } |
| |
| void SubGraph::SortLanguageForMin () |
| { |
| int *sortList; |
| |
| if (numArc <= 1) { |
| sortList= new int [numArc+2]; |
| sortList[0]= 0; |
| if (forwardList) |
| delete [] forwardList; |
| forwardList= sortList; |
| sortNum= numArc; |
| return; |
| } |
| SortLanguageAtIndicesForMin (-1, -1); |
| return; |
| } |
| |
| void SubGraph::SortLanguageAtIndicesForMin (int begIx, int endIx) |
| { |
| int ii, jj, hired, retd; |
| int holdArc, *sortList; |
| |
| if (begIx < 0) |
| begIx= 0; |
| if (endIx < 0) |
| endIx= numArc; |
| |
| if (endIx <= begIx) |
| return; |
| |
| sortList= new int [numArc+2]; |
| for (ii= 0; ii < sortNum && ii < numArc; ii++) |
| sortList[ii]= forwardList[ii]; |
| for (ii= begIx; ii < endIx; ii++) |
| sortList[ii]= ii; |
| sortList--; |
| |
| /* Hiring |
| */ |
| hired= (numArc >> 1)+1; |
| while (hired-- > 1) { |
| holdArc= sortList[hired]; |
| ii= hired; |
| jj= hired << 1; |
| while (jj <= numArc) { |
| if (jj < numArc && ARC_COMPARE_MIN (sortList[jj], sortList[jj+1]) <= 0 ) |
| jj++; |
| if (ARC_COMPARE_MIN (holdArc, sortList[jj]) < 0) { |
| sortList[ii]= sortList[jj]; |
| ii= jj; |
| jj <<= 1; |
| } |
| else |
| break; |
| } |
| sortList[ii]= holdArc; |
| } |
| |
| /* Retiring |
| */ |
| retd= numArc; |
| while (retd > 0) { |
| holdArc= sortList[retd]; |
| sortList[retd]= sortList[1]; |
| if (--retd == 1) { |
| sortList[1]= holdArc; |
| break; |
| } |
| ii= 1; |
| jj= 2; |
| while (jj <= retd) { |
| if (jj < retd && ARC_COMPARE_MIN (sortList[jj], sortList[jj+1]) <= 0) |
| jj++; |
| if (ARC_COMPARE_MIN (holdArc, sortList[jj]) < 0) { |
| sortList[ii]= sortList[jj]; |
| ii= jj; |
| jj <<= 1; |
| } |
| else |
| break; |
| } |
| sortList[ii]= holdArc; |
| } |
| sortList++; |
| |
| if (forwardList) |
| delete [] forwardList; |
| forwardList= sortList; |
| sortNum= numArc; |
| |
| /* Now carry out some checks |
| */ |
| int checkSort = CheckSort(); |
| if(checkSort == 0) { |
| // printf("assert(0) in SubGraph::CheckSort %d\n", checkSort); |
| // hmm .. this seems harmless but ...! |
| // assert(checkSort); |
| } |
| |
| return; |
| } |
| |