14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* FILE:		sub_min.cpp
24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  DATE MODIFIED:	31-Aug-07
34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  DESCRIPTION:	Part of the  SREC graph compiler project source files.
44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *
54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Copyright 2007, 2008 Nuance Communciations, Inc.                               *
64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the 'License');          *
84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  you may not use this file except in compliance with the License.         *
94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  You may obtain a copy of the License at                                  *
114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0                           *
124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software      *
144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  distributed under the License is distributed on an 'AS IS' BASIS,        *
154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  See the License for the specific language governing permissions and      *
174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  limitations under the License.                                           *
184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *---------------------------------------------------------------------------*/
204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <iostream>
224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <string>
234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <assert.h>
2466d9f39f64360565c0b7176218412135b8242528Scott Tsai#include <cstdio>
254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "sub_grph.h"
274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define SYMBOL_COMPARE(x,y) (arc[x]->CompareSymbol(arc[y]))
294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define COMPARE(x,y) (arc[x]->Compare(arc[y]))
304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//  Minimization to facilitate moving output symbols - mainly for phoneme networks
324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//      Check partial merge
334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//      Move the output symbol if only one node
344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*
364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic int checkEntry (int *itemList, int count, int item);
374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic int checkEntry (int *itemList, int count, int item)
394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (int ii= 0; ii < count; ii++)
414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (item == itemList[ii])
424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            return ii;
434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return -1;
444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project*/
464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid SubGraph::ViewNode (int currId)
484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int  rix;
504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    printf ("Node: %d\n", currId);
524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    rix= FindFromIndex (currId);
534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (rix < 0)
544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return;
554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    while (rix < numArc && arc[forwardList[rix]]->GetFromId() == currId) {
564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        arc[forwardList[rix]]->Print();
574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        rix++;
584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return;
604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectbool SubGraph::EquivalenceTestForward (int firstId, int secondId, int *equivMap)
644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int  fix, six, fnxt, snxt, tof, tos, count;
664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    assert (firstId != secondId);
684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    fix= FindFromIndex (firstId);
694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    six= FindFromIndex (secondId);
704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (fix < 0 || six < 0)
714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return false;
724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    count= 0;
744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    do {
754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        //  Move to next valid transitions
774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        while (fix < numArc && arc[forwardList[fix]]->GetFromId() == firstId
784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            && arc[forwardList[fix]]->GetToId() == DISCARD_LABEL)
794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            fix++;
804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (fix < numArc && arc[forwardList[fix]]->GetFromId() == firstId)
814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            fnxt= arc[forwardList[fix]]->GetFromId();
824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        else
834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            fnxt= -1;
844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        while (six < numArc && arc[forwardList[six]]->GetFromId() == secondId
864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            && arc[forwardList[six]]->GetToId() == DISCARD_LABEL)
874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            six++;
884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (six < numArc && arc[forwardList[six]]->GetFromId() == secondId)
894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            snxt= arc[forwardList[six]]->GetFromId();
904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        else
914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            snxt= -1;
924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (fnxt != firstId && snxt != secondId)
944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            return true;
954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        else if (fnxt != firstId || snxt != secondId)
964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            return false;
974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	tos= arc[forwardList[six]]->GetToId();
994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	tof= arc[forwardList[fix]]->GetToId();
1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        // printf ("Debug inner %d %d, %d %d\n", tof, tos, equivMap[tof], equivMap[tos]);
1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	// if (tof >= 0)		bogus assert
1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    // assert (tof == equivMap[tof]);
1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	// if (tos >= 0)
1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    // assert (tos == equivMap[tos]);
1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        //  Test
1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (!arc[forwardList[fix]]->HasSameLabels (arc[forwardList[six]])
1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    || tos != tof)
1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            return false;
1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	count++;
1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        fix++;
1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        six++;
1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }  while (fnxt >= 0 && snxt >= 0);
1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return false;
1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid SubGraph::IdentifyEquivalence (int *depthMap, int *equivMap)
1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int ii, jj, dd, maxDepth, count, itCnt;
1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    maxDepth= 0;
1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ii= 0; ii < numVertex; ii++) {
1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (maxDepth < depthMap[ii])
1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            maxDepth= depthMap[ii];
1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    itCnt= 0;
1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    do {
1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        count= 0;
1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        for (dd= 0; dd <= maxDepth; dd++)
1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            for (ii= 0; ii < numVertex; ii++)
1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                if (depthMap[ii] == dd && ii == equivMap[ii]) {
1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    CheckForChangeAndResort (ii, equivMap);
1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    for (jj= ii+1; jj < numVertex; jj++)
1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        if (depthMap[jj] == dd && jj == equivMap[jj]) {
1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            // Equivalence test
1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            CheckForChangeAndResort (jj, equivMap);
1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            // printf ("Try %d %d, ", ii, jj);
1424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            if (EquivalenceTestForward (ii, jj, equivMap)) {
1434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                equivMap[jj]= ii;
1444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                // printf ("Merged %d %d\n", ii, jj);
1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                count++;
1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            }
1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        }
1484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                }
1494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        itCnt++;
1514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        // printf ("Total %d mergers\n", count);
1524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    } while (count > 0 && itCnt < MAXITS);
1534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return;
1554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid SubGraph::CheckForChangeAndResort (int currId, int *mapList)
1584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
1594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int  rix, rixBegin, nextId;
1604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    bool needSort;
1614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    needSort= false;
1634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    rixBegin= rix= FindFromIndex (currId);
1644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (rix < 0)
1654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return;
1664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    while (rix < numArc && arc[forwardList[rix]]->GetFromId() == currId) {
1674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        nextId= arc[forwardList[rix]]->GetToId();
1684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (nextId >= 0 && mapList[nextId] != nextId) {
1694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            needSort= true;
1704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            arc[forwardList[rix]]->AssignToId(mapList[nextId]);
1714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
1724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        rix++;
1734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    //  Resort
1764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (needSort)
1774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        RemoveDuplicatesAtNode (rixBegin, rix);
1784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return;
1804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid SubGraph::DeterminizeAtVertex (int baseId, DetCache *cache)
1834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
1844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int  fix, six, firstId, secondId, vertEnd;
1854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    fix= FindFromIndex (baseId);
1874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (fix < 0)
1884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return;
1894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    // Remove duplicates
1914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    vertEnd= fix;
1924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    six= -1;
1934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    while (vertEnd < sortNum && arc[forwardList[vertEnd]]->GetFromId() == baseId) {
1944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        vertEnd++;
1954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    vertEnd++;
1974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    //  Iteration over first node
1994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    firstId= -1;
2004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    while (fix < sortNum && arc[forwardList[fix]]->GetFromId() == baseId) {
2014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        //  Iterator for firstId
2034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        while (fix < sortNum && arc[forwardList[fix]]->GetFromId() == baseId
2044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            && (arc[forwardList[fix]]->GetToId() == firstId
2054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		    || arc[forwardList[fix]]->GetInput() == TERMINAL_LABEL
2064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		    || arc[forwardList[fix]]->GetInput() == DISCARD_LABEL))
2074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            fix++;
2084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	// Terminal Condition
2104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	if (fix >= sortNum || arc[forwardList[fix]]->GetFromId() != baseId)
2114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    break;
2124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	else
2134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    firstId= arc[forwardList[fix]]->GetToId();
2144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        //  Iteration over second node
2164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	six= fix;
2174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        secondId= firstId;
2184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        while (six < sortNum && arc[forwardList[six]]->GetFromId() == baseId) {
2194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	        //  Iterator for secondId
2214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            while (six < sortNum && arc[forwardList[six]]->GetFromId() == baseId
2224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                && (arc[forwardList[six]]->GetToId() == secondId
2234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		        || arc[forwardList[six]]->GetInput() == TERMINAL_LABEL
2244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		        || arc[forwardList[six]]->GetInput() == DISCARD_LABEL))
2254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		        six++;
2264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	        //  Terminal condition
2284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	        if (six >= sortNum || arc[forwardList[six]]->GetFromId() != baseId)
2294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		    break;
2304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	        else
2314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		    secondId= arc[forwardList[six]]->GetToId();
2324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            //  Now we have both Ids worked out
2344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	        assert (firstId >= 0);
2354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	        assert (secondId >= 0);
2364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                assert (arc[forwardList[fix]]->GetInput() != DISCARD_LABEL);
2374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                assert (arc[forwardList[six]]->GetInput() != DISCARD_LABEL);
2384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (PairwiseDeterminize (baseId, firstId, fix, secondId, six, cache) > 0) {
2404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                SortLanguageAtSortIndices (fix, vertEnd);
2414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                //  Are we done with the first node?
2434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                while (fix < sortNum && arc[forwardList[fix]]->GetFromId() == baseId
2444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                   && arc[forwardList[fix]]->GetInput() == DISCARD_LABEL)
2454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    fix++;
2464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	            //  Terminal condition
2484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	            if (fix >= sortNum || arc[forwardList[fix]]->GetFromId() != baseId
2494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                 || arc[forwardList[fix]]->GetToId() != firstId)
2504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		            break;
2514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
2524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
2534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return;
2554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
2564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint SubGraph::PairwiseDeterminize (int baseId, int firstId, int fixStart, int secondId,
2584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                   int sixStart, DetCache *cache)
2594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
2604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int  fix, six, fmiss, smiss, nmatch, symTst, newId;
2614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    bool isCached;
2624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    fix= fixStart;
2644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    six= sixStart;
2654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    assert (arc[forwardList[fix]]->GetInput() != DISCARD_LABEL);
2674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    assert (arc[forwardList[six]]->GetInput() != DISCARD_LABEL);
2684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    //  Count
2704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    isCached= false;
2714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    fmiss= smiss= nmatch= 0;
2724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    newId= -1;
2734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    while (six < sortNum && fix < sortNum) {
2744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        assert (arc[forwardList[fix]]->GetInput() != DISCARD_LABEL);
2764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        assert (arc[forwardList[six]]->GetInput() != DISCARD_LABEL);
2774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        symTst= SYMBOL_COMPARE (forwardList[fix], forwardList[six]);
2794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (symTst == 0) {
2804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (newId == -1) {
2814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                newId= cache->QueryEntry (firstId, secondId);
2824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		if (newId < 0)
2834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    newId= NewVertexId ();
2844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                else
2854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    isCached= true;
2864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		// printf ("Forming %d with %d and %d at %d\n", newId, firstId, secondId, baseId);
2874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
2884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            //  Assign second to new Vertex
2904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            arc[forwardList[six]]->AssignToId (newId);
2914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            //  Assign first to DISCARD Index
2934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            arc[forwardList[fix]]->AssignInput (DISCARD_LABEL);
2944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            //  Increment to next
2964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            do {
2974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                fix++;
2984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            } while (fix < sortNum && arc[forwardList[fix]]->GetInput() == DISCARD_LABEL);
2994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (fix >= sortNum || arc[forwardList[fix]]->GetFromId() != baseId
3004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                || arc[forwardList[fix]]->GetToId() != firstId)
3014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                fix= sortNum;
3024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            do {
3044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                six++;
3054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            } while (six < sortNum && arc[forwardList[six]]->GetInput() == DISCARD_LABEL);
3064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (six >= sortNum || arc[forwardList[six]]->GetFromId() != baseId
3074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                || arc[forwardList[six]]->GetToId() != secondId)
3084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                six= sortNum;
3094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            nmatch++;
3114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
3124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        else if (symTst < 0) {
3134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            do {
3144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                fix++;
3154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            } while (fix < sortNum && arc[forwardList[fix]]->GetInput() == DISCARD_LABEL);
3164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (fix >= sortNum || arc[forwardList[fix]]->GetFromId() != baseId
3174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                || arc[forwardList[fix]]->GetToId() != firstId)
3184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                fix= sortNum;
3194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            fmiss++;
3204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
3214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        else if (symTst > 0) {
3224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            do {
3234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                six++;
3244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            } while (six < sortNum && arc[forwardList[six]]->GetInput() == DISCARD_LABEL);
3254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (six >= sortNum || arc[forwardList[six]]->GetFromId() != baseId
3264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                || arc[forwardList[six]]->GetToId() != secondId)
3274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                six= sortNum;
3284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            smiss++;
3294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
3304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
3314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    // SortLanguageAtSortIndices (fixStart, fix);
3334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (newId >= 0) {
3354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (isCached == false) {
3364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            // numLast= numArc;
3374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            MergeVertices (newId, firstId, secondId);
3384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            cache->AddEntry (newId, firstId, secondId);
3394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            // UpdateVisitationCache (numLast);
3404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
3414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        assert (nmatch > 0);
3424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
3434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    //  Update fan-in count
3454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (nmatch > 0) {
3464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        // printf ("Merging %d %d to create %d\n", firstId, secondId, newId);
3474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        for (int ii= 0; ii < nmatch; ii++) {
3484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            // IncNodeProperty (newId);
3494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            IncVisitationCache (newId);
3504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            DecVisitationCache (firstId);
3514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            DecVisitationCache (secondId);
3524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
3534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
3544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return nmatch;
3554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
3564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid SubGraph::MergeVertices (int newId, int firstId, int secondId)
3584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
3594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int fix, six, symTst, numStart;
3604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    NUANArc *arcOne;
3614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    numStart= numArc;
3634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    fix= FindFromIndex (firstId);
3644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    six= FindFromIndex (secondId);
3654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (fix < 0 || six < 0) {
3664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (fix >= 0)
3674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            while (fix < sortNum && arc[forwardList[fix]]->GetFromId() == firstId) {
3684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                if (arc[forwardList[fix]]->GetInput() != DISCARD_LABEL)
3694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    InheritArc (arc[forwardList[fix]], newId);
3704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                fix++;
3714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
3724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        else if (six >= 0)
3734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            while (six < sortNum && arc[forwardList[six]]->GetFromId() == secondId) {
3744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                if (arc[forwardList[six]]->GetInput() != DISCARD_LABEL)
3754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    InheritArc (arc[forwardList[six]], newId);
3764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                six++;
3774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
3784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
3794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else {
3804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        while (six < sortNum && fix < sortNum) {
3814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            symTst= SYMBOL_COMPARE (forwardList[fix], forwardList[six]);
3834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (symTst == 0) {
3854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                if (arc[forwardList[fix]]->GetToId() == firstId
3864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                 && arc[forwardList[six]]->GetToId() == secondId) {
3874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    arcOne= InheritArc (arc[forwardList[fix]], newId);
3884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    arcOne->AssignToId (newId);
3894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                }
3904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                else if (arc[forwardList[fix]]->GetToId()
3914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                 == arc[forwardList[six]]->GetToId()) {
3924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    InheritArc (arc[forwardList[fix]], newId);
3934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		}
3944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                else {
3954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    InheritArc (arc[forwardList[fix]], newId);
3964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    InheritArc (arc[forwardList[six]], newId);
3974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                }
3984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                //  Increment to next
4004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                do {
4014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    fix++;
4024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                } while (fix < sortNum && arc[forwardList[fix]]->GetInput() == DISCARD_LABEL);
4034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                if (fix >= sortNum || arc[forwardList[fix]]->GetFromId() != firstId
4044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    || arc[forwardList[fix]]->GetFromId() != firstId)
4054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    fix= sortNum;
4064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                do {
4084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    six++;
4094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                } while (six < sortNum && arc[forwardList[six]]->GetInput() == DISCARD_LABEL);
4104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                if (six >= sortNum || arc[forwardList[six]]->GetFromId() != secondId)
4114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    six= sortNum;
4124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
4134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            else if (symTst < 0) {
4144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                InheritArc (arc[forwardList[fix]], newId);
4154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                do {
4164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    fix++;
4174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                } while (fix < sortNum && arc[forwardList[fix]]->GetInput() == DISCARD_LABEL);
4184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                if (fix >= sortNum || arc[forwardList[fix]]->GetFromId() != firstId
4194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    || arc[forwardList[fix]]->GetFromId() != firstId)
4204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    fix= sortNum;
4214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
4224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            else if (symTst > 0) {
4234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                InheritArc (arc[forwardList[six]], newId);
4244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                do {
4254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    six++;
4264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                } while (six < sortNum && arc[forwardList[six]]->GetInput() == DISCARD_LABEL);
4274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                if (six >= sortNum || arc[forwardList[six]]->GetFromId() != secondId
4284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    || arc[forwardList[six]]->GetFromId() != secondId)
4294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    six= sortNum;
4304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
4314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
4324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        while (fix < sortNum && arc[forwardList[fix]]->GetFromId() == firstId) {
4344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (arc[forwardList[fix]]->GetInput() != DISCARD_LABEL)
4354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                InheritArc (arc[forwardList[fix]], newId);
4364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            fix++;
4374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
4384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        while (six < sortNum && arc[forwardList[six]]->GetFromId() == secondId) {
4404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (arc[forwardList[six]]->GetInput() != DISCARD_LABEL)
4414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                InheritArc (arc[forwardList[six]], newId);
4424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            six++;
4434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
4444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
4454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    //  Update the sort list
4474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    UpdateSortForLanguage ();
4484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    // RemoveDuplicatesAtNode (numStart, numArc);
4494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    // ViewNode (newId);
4504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    assert (CheckSort());
4514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    // printf ("Merging %d %d to create %d\n", firstId, secondId, newId);
4534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return;
4554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
4564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid SubGraph::SetupVisitationCache ()
4584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
4594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int ii;
4604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    CreateNodeProperty ();
4624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ii= 0; ii < numArc; ii++)
4634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (arc[ii]->GetInput() != DISCARD_LABEL && arc[ii]->GetToId() >= 0)
4644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            IncNodeProperty (arc[ii]->GetToId());
4654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return;
4664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
4674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid SubGraph::ClearVisitationCache ()
4694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
4704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    DeleteNodeProperty ();
4714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return;
4724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
4734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid SubGraph::UpdateVisitationCache (int startNo)
4754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
4764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int ii;
4774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ii= startNo; ii < numArc; ii++)
4794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (arc[ii]->GetInput() != DISCARD_LABEL && arc[ii]->GetToId() >= 0) {
4804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            IncNodeProperty (arc[ii]->GetToId());
4814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            // std::cout << " (" << arc[ii]->GetToId() << " " << QueryNodeProperty (arc[ii]->GetToId()) << ") ";
4824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
4834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    // std::cout << std::endl;
4844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return;
4854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
4864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid SubGraph::DecVisitationCache (int currId)
4884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
4894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int rix;
4904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    DecNodeProperty (currId);
4924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    // std::cout << " [" << currId << " " << QueryNodeProperty (currId) << "] ";
4934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (QueryNodeProperty (currId) <= 0) {
4944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        // std::cout << " [" << currId << "] ";
4954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        rix= FindFromIndex (currId);
4964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (rix < 0)
4974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            return;
4984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        while (rix < sortNum && arc[forwardList[rix]]->GetFromId() == currId) {
4994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (arc[forwardList[rix]]->GetInput() != DISCARD_LABEL
5004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                && arc[forwardList[rix]]->GetToId() >= 0) {
5014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                if (arc[forwardList[rix]]->GetFromId() == arc[forwardList[rix]]->GetToId())
5024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    DecNodeProperty (currId);
5034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                else if (QueryNodeProperty (arc[forwardList[rix]]->GetToId()) > 0)
5044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    DecVisitationCache (arc[forwardList[rix]]->GetToId());
5054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
5064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            rix++;
5074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
5084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
5094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return;
5104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
5114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid SubGraph::IncVisitationCache (int currId)
5134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
5144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int rix;
5154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (QueryNodeProperty (currId) <= 0) {
5174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        IncNodeProperty (currId);
5184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        // std::cout << " (" << currId << ") ";
5194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        rix= FindFromIndex (currId);
5204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (rix < 0)
5214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            return;
5224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        while (rix < sortNum && arc[forwardList[rix]]->GetFromId() == currId) {
5234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (arc[forwardList[rix]]->GetInput() != DISCARD_LABEL
5244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                && arc[forwardList[rix]]->GetToId() >= 0) {
5254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                // IncNodeProperty (arc[forwardList[rix]]->GetToId());
5264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		// if (currId != arc[forwardList[rix]]->GetToId())
5274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    IncVisitationCache (arc[forwardList[rix]]->GetToId());
5284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
5294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            rix++;
5304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
5314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
5324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else
5334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        IncNodeProperty (currId);
5344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    // std::cout << " (" << currId << " " << QueryNodeProperty (currId) << ") ";
5354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return;
5364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
5374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint SubGraph::VisitationConsistencyCheck ()
5394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
5404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int ii, failCount;
5414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int *nodeCount= new int [numVertex];
5434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    UpdateVertexCount (0);
5454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    // std::cout << "Count: ";
5474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ii= 0; ii <numVertex; ii++) {
5484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        // std::cout << ii << " (" << vertexProp[ii] << ") ";
5494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        nodeCount[ii]= 0;
5504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
5514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    // std::cout << std::endl;
5524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ii= 0; ii <numArc; ii++)
5534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (arc[ii]->GetInput() != DISCARD_LABEL && arc[ii]->GetToId() >= 0
5544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            && (vertexProp[arc[ii]->GetFromId()] > 0 || arc[ii]->GetFromId() == startId))
5554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            nodeCount[arc[ii]->GetToId()]++;
5564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    failCount= 0;
5574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    // std::cout << "Failure list: ";
5584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ii= 0; ii <numVertex; ii++)
5594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (vertexProp[ii] != nodeCount[ii]) {
5604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            // std::cout << ii << " (" << vertexProp[ii] << " " << nodeCount[ii] << ") ";
5614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            failCount++;
5624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
5634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    // std::cout << std::endl;
5644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    // return failCount;
5664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    delete [] nodeCount;
5674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return 0;
5694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
570