| /* FILE: sub_base.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" |
| |
| |
| SubGraph::SubGraph (SubGraph *baseG) |
| { |
| int count= strlen(baseG->title); |
| title= new char [count+1]; |
| strcpy (title, baseG->title); |
| ruleId= baseG->ruleId; |
| arc= new NUANArc * [BLKSIZE]; |
| popOp= 0; |
| numVertex= baseG->numVertex; |
| lastScope= SCOPE_ROOT; |
| startId= baseG->startId; |
| lastId= baseG->lastId; |
| endId= baseG->endId; |
| forwardList= 0; |
| backwardList= 0; |
| sortNum= 0; |
| numArc= 0; |
| CopyFastArcs (baseG, 0, baseG->numArc, 0, -1, -1, -1, -1); |
| UpdateVertexCount (0); |
| |
| return; |
| } |
| |
| int SubGraph::NewVertexId () |
| { |
| return (numVertex++); |
| } |
| |
| void SubGraph::AllocateSpaceForArc () |
| { |
| if (numArc == 0) { |
| arc= new NUANArc * [BLKSIZE]; |
| } |
| if (numArc%BLKSIZE == 0) { |
| NUANArc **new_arc= new NUANArc * [numArc+BLKSIZE]; |
| for (int ii= 0; ii < numArc; ii++) |
| new_arc[ii]= arc[ii]; |
| delete [] arc; |
| arc= new_arc; |
| } |
| } |
| |
| NUANArc *SubGraph::CreateArc (int iLabel, int oLabel, int from, int to) |
| { |
| assert (!(iLabel == NONE_LABEL && from == to)); |
| AllocateSpaceForArc (); |
| NUANArc *arc_one= new NUANArc (iLabel, oLabel, from, to); |
| arc[numArc]= arc_one; |
| numArc++; |
| return arc_one; |
| } |
| |
| NUANArc *SubGraph::InheritArc (NUANArc *arcBase, int id) |
| { |
| AllocateSpaceForArc (); |
| NUANArc *arc_one= new NUANArc (arcBase); |
| arc_one->AssignFromId (id); |
| arc[numArc]= arc_one; |
| numArc++; |
| return arc_one; |
| } |
| |
| NUANArc *SubGraph::InheritReverseArc (NUANArc *arcBase, int id) |
| { |
| AllocateSpaceForArc (); |
| NUANArc *arc_one= new NUANArc (arcBase); |
| arc_one->AssignToId (id); |
| arc[numArc]= arc_one; |
| numArc++; |
| return arc_one; |
| } |
| |
| NUANArc *SubGraph::InheritReverseArcWithTag (NUANArc *arcBase, int id, int tagId) |
| { |
| AllocateSpaceForArc (); |
| NUANArc *arc_one= new NUANArc (arcBase); |
| arc_one->AssignToId (id); |
| arc_one->AssignOutput (tagId); |
| arc[numArc]= arc_one; |
| numArc++; |
| return arc_one; |
| } |
| |
| NUANArc *SubGraph::CreateCopyWithOutput (NUANArc *arcBase, int id) |
| { |
| AllocateSpaceForArc (); |
| NUANArc *arc_one= new NUANArc (arcBase); |
| arc_one->AssignOutput (id); |
| arc[numArc]= arc_one; |
| numArc++; |
| return arc_one; |
| } |
| |
| void SubGraph::CopyFastArcs (SubGraph *subG, int startLoc, int endLoc, int offset, int headId, int newHeadId, int tailId, int newTailId) |
| { |
| NUANArc *arc_one; |
| |
| for (int ii= startLoc; ii < endLoc; ii++) { |
| if (numArc%BLKSIZE == 0) { |
| NUANArc **new_arc= new NUANArc * [numArc+BLKSIZE]; |
| for (int ii= 0; ii < numArc; ii++) |
| new_arc[ii]= arc[ii]; |
| delete [] arc; |
| arc= new_arc; |
| } |
| arc_one= new NUANArc (subG->arc[ii], offset, headId, newHeadId, tailId, newTailId); |
| arc[numArc]= arc_one; |
| numArc++; |
| } |
| return; |
| } |
| |
| void SubGraph::Print () |
| { |
| int loc; |
| |
| printf ("Graph %s (%d %d)\n", title, startId, lastId); |
| for (int ii= 0; ii < numArc; ii++) { |
| loc= forwardList[ii]; |
| // loc= ii; |
| arc[loc]->Print(); |
| } |
| return; |
| } |
| |
| void SubGraph::PrintText () |
| { |
| int loc; |
| |
| printf ("Graph %s (%d %d)\n", title, startId, lastId); |
| for (int ii= 0; ii < numArc; ii++) { |
| loc= forwardList[ii]; |
| // loc= ii; |
| arc[loc]->PrintText(); |
| } |
| return; |
| } |
| |
| void SubGraph::ReverseDepthOnTerminal (int *depthMap) |
| { |
| for (int ii= 0; ii < numArc; ii++) |
| if (arc[ii]->GetInput() == TERMINAL_LABEL) |
| ReverseDepthData (arc[ii]->GetFromId(), depthMap, 1); |
| return; |
| } |
| |
| void SubGraph::ReverseDepthData (int startId, int *depthMap, int depth) |
| { |
| int rix, nextId, nextInp; |
| |
| if (depthMap[startId] > depth) |
| depthMap[startId]= depth; |
| else |
| return; |
| rix= FindToIndex (startId); |
| if (rix < 0) |
| return; |
| while (rix < numArc && arc[backwardList[rix]]->GetToId() == startId) { |
| nextId= arc[backwardList[rix]]->GetFromId(); |
| nextInp= arc[backwardList[rix]]->GetInput(); |
| if (nextId >= 0 && nextInp != DISCARD_LABEL) |
| ReverseDepthData (nextId, depthMap, depth+1); |
| rix++; |
| } |
| return; |
| } |
| |
| void SubGraph::ForwardDepthData (int startId, int *depthMap, int depth) |
| { |
| int rix, nextId, nextInp; |
| |
| if (depthMap[startId] > depth) |
| depthMap[startId]= depth; |
| else |
| return; |
| rix= FindFromIndex (startId); |
| if (rix < 0) |
| return; |
| while (rix < numArc && arc[forwardList[rix]]->GetFromId() == startId) { |
| nextId= arc[forwardList[rix]]->GetToId(); |
| nextInp= arc[forwardList[rix]]->GetInput(); |
| if (nextId >= 0 && nextInp != DISCARD_LABEL) |
| ForwardDepthData (nextId, depthMap, depth+1); |
| rix++; |
| } |
| return; |
| } |
| |
| void SubGraph::RemoveUnvisitedArcs (int initialId, int finalId) |
| { |
| int ii; |
| int *forwardDepth= new int [numVertex]; |
| int *reverseDepth= new int [numVertex]; |
| |
| for (ii= 0; ii < numVertex; ii++) |
| forwardDepth[ii]= reverseDepth[ii]= MAXNUM; // TODO: review |
| SortLanguage(); |
| SortLanguageReverse(); |
| |
| ForwardDepthData (initialId, forwardDepth, 1); |
| if (finalId >= 0) |
| ReverseDepthData (finalId, reverseDepth, 1); |
| ReverseDepthOnTerminal (reverseDepth); |
| |
| for (ii= 0; ii < numVertex; ii++) { |
| if (forwardDepth[ii] == MAXNUM) |
| forwardDepth[ii]= -1; |
| if (reverseDepth[ii] == MAXNUM) |
| reverseDepth[ii]= -1; |
| } |
| RemoveMarkedNodes (forwardDepth, reverseDepth); |
| delete [] forwardDepth; |
| delete [] reverseDepth; |
| return; |
| } |
| |
| void SubGraph::RemoveMarkedNodes (int *forwardDepth, int *reverseDepth) |
| { |
| int ii, currId, incId, outId; |
| |
| currId= 0; |
| for (ii= 0; ii < numArc; ii++) { |
| incId= arc[ii]->GetFromId(); |
| outId= arc[ii]->GetToId(); |
| assert (outId == DISCARD_LABEL || outId == TERMINAL_LABEL || outId >= 0); |
| if (incId != DISCARD_LABEL && outId != DISCARD_LABEL |
| && arc[ii]->GetInput() != DISCARD_LABEL |
| && forwardDepth[incId] > 0 |
| && (outId == TERMINAL_LABEL || reverseDepth[outId] > 0)) { |
| arc[currId]= arc[ii]; |
| currId++; |
| } |
| else |
| delete arc[ii]; |
| } |
| for (ii= currId; ii < numArc; ii++) |
| arc[ii]= 0; |
| numArc= currId; |
| return; |
| } |
| |
| void SubGraph::RemoveDiscardedArcs () |
| { |
| int ii, currId, outId, inpId; |
| |
| currId= 0; |
| for (ii= 0; ii < numArc; ii++) { |
| outId= arc[ii]->GetToId(); |
| inpId= arc[ii]->GetInput(); |
| if (outId != DISCARD_LABEL && inpId != DISCARD_LABEL) { |
| arc[currId]= arc[ii]; |
| currId++; |
| } |
| else |
| delete arc[ii]; |
| } |
| for (ii= currId; ii < numArc; ii++) |
| arc[ii]= 0; |
| numArc= currId; |
| return; |
| } |
| |
| void SubGraph::MapGraphVertices (int *equivMap) |
| { |
| int ii, fromId, toId; |
| |
| for (ii= 0; ii < numArc; ii++) { |
| fromId= arc[ii]->GetFromId(); |
| if (fromId >= 0) |
| if (equivMap[fromId] != fromId) |
| arc[ii]->AssignInput (DISCARD_LABEL); |
| toId= arc[ii]->GetToId(); |
| if (toId >= 0) |
| if (equivMap[toId] != toId) |
| arc[ii]->AssignToId (equivMap[toId]); |
| } |
| return; |
| } |
| |
| void SubGraph::DebugPrintDirective (char *dirrData) |
| { |
| for (int ii= 0; ii < (popOp/7); ii++) |
| printf (" "); |
| printf ("%s\n", dirrData); |
| return; |
| } |
| |
| void SubGraph::DebugPrintLabel (int labId) |
| { |
| for (int ii= 0; ii <= (popOp/7); ii++) |
| printf (" "); |
| printf ("%d\n", labId); |
| return; |
| } |
| |
| void SubGraph::ClearLabelledConnections (int labItem) |
| { |
| for (int ii= 0; ii < numArc; ii++) { |
| if (arc[ii]->GetInput() == labItem) |
| arc[ii]->AssignToId (DISCARD_LABEL); |
| } |
| return; |
| } |
| |
| void SubGraph::ClearRuleIds () |
| { |
| for (int ii= 0; ii < numArc; ii++) { |
| if (arc[ii]->GetInput() < 0 && arc[ii]->GetInput() > NONE_LABEL) |
| arc[ii]->AssignToId (DISCARD_LABEL); |
| } |
| return; |
| } |
| |
| void SubGraph::ClearOutputs () |
| { |
| for (int ii= 0; ii < numArc; ii++) |
| arc[ii]->AssignOutput (NONE_LABEL); |
| return; |
| } |