14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*---------------------------------------------------------------------------*
24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  astar.c  *
34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Copyright 2007, 2008 Nuance Communciations, Inc.                               *
54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the 'License');          *
74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  you may not use this file except in compliance with the License.         *
84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  You may obtain a copy of the License at                                  *
104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0                           *
114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software      *
134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  distributed under the License is distributed on an 'AS IS' BASIS,        *
144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  See the License for the specific language governing permissions and      *
164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  limitations under the License.                                           *
174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *---------------------------------------------------------------------------*/
194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "pstdio.h"
214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "passert.h"
224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include"srec_sizes.h"
244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include"search_network.h"
254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include"srec.h"
264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include"srec_context.h"
274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include"word_lattice.h"
284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "portable.h"
294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "srec_stats.h"
304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "astar.h"
314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "astar_pphash.h"
324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#ifdef SET_RCSID
344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic const char *rcsid = 0 ? (const char *) &rcsid :
354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                           "$Id: astar.c,v 1.19.4.9 2008/04/30 15:12:15 dahan Exp $";
364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define PRINT_ASTAR_SOMEWHAT  0
394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define PRINT_ASTAR_DETAILS   0
404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define PRINT_ASTAR_QBT_DETAILS   0 /* Quick Back Trace */
414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define MAX_NBEST_LEN        32
424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define NBEST_LEN_MARGIN     10
434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define MAX_NUM_PARPS       400 /* 3*MAX_NBEST_LEN*MAX_WORDS_PER_COMPLETE_PATH need better dup
444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project													         check on complete paths */
454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define ASTAR_PRUNE_DELTA 20000
464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define DEBUG_PARP_MANAGEMENT 0
474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_DETAILS
494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic int do_draw_as_dotty = 0;
504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic int do_draw_file_idx = 0;
514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint astar_draw_tree_as_dotty(const char* file, srec* rec, AstarStack* stack);
534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*
564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  The word graph is represented as an arc_token_list,
574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  arc_token's are chained together 2 linked lists,
584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  arc_token->first_next_arc ... like a "TO" node
594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  arc_token->next_arc_index ... a linked list of arcs leaving the same node
604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  get_arc_for_word() finds the arc_token for a particular extension
624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  backward though the word graph (ie. forward through the reverse word graph)
634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project*/
654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define ARC_TOKEN_ONE (arc_token*)1
674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectarc_token* get_arc_for_word(arc_token* atoken, wordID word,
684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            void* context_void,
694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            wordID terminal_word)
704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  srec_context* context = (srec_context*)context_void;
724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  arc_token* arc_token_list = context->arc_token_list;
734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  arc_token* tmp;
744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  wordmap* wmap = context->olabels;
754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (atoken == ARC_TOKEN_ONE)
774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* log_report("Warning:  bad thing is happening word=%d\n", word); */
794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return 0;
804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  else if (atoken == 0)
824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    arc_token root_arc;
844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    root_arc.first_next_arc = ARC_TOKEN_LNK(arc_token_list, 0);
854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    root_arc.next_token_index = ARC_TOKEN_NULL;
864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    root_arc.ilabel = root_arc.olabel = 0;
874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return get_arc_for_word(&root_arc, word, context_void, terminal_word);
884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* the arc token is NULL for partial paths just starting; but
904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       the word graph has nasty epsilons at the beginning, we'll remove
914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       them later, but must handle them in the mean time. */
924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    atoken = &arc_token_list[0];
934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (; atoken; atoken = ARC_TOKEN_PTR(arc_token_list, atoken->next_token_index))
944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (atoken->ilabel == word)
964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return atoken;
974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      else if (atoken->ilabel == WORD_EPSILON_LABEL)
984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        for (tmp = ARC_TOKEN_PTR(arc_token_list, atoken->first_next_arc); tmp;
1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project             tmp = ARC_TOKEN_PTR(arc_token_list, tmp->next_token_index))
1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          if (tmp->ilabel == word)
1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            return tmp;
1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      else if (atoken->ilabel < wmap->num_slots)
1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (wordmap_whether_in_rule(wmap, word, atoken->ilabel))
1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          return atoken;
1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return 0;
1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  else if (word == terminal_word)
1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* -pau- LABEL, the word graph does not seem to have them! */
1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    tmp = ARC_TOKEN_PTR(arc_token_list, atoken->first_next_arc);
1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!tmp)
1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return ARC_TOKEN_ONE;
1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else if (tmp->first_next_arc == ARC_TOKEN_NULL && (tmp->ilabel == MAXwordID || tmp->ilabel == terminal_word))
1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return ARC_TOKEN_ONE;
1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else
1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      /* again more weirdness in the output graph format1
1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      might be due to multiple endnodes? */
1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      for (tmp = ARC_TOKEN_PTR(arc_token_list, atoken->first_next_arc); tmp;
1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project           tmp = ARC_TOKEN_PTR(arc_token_list, tmp->next_token_index))
1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (tmp->ilabel == MAXwordID && tmp->first_next_arc == ARC_TOKEN_NULL)
1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          return ARC_TOKEN_ONE;
1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return 0;
1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  else
1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_DETAILS
1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    printf("word %d allowed? ", word);
1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (atoken->first_next_arc == ARC_TOKEN_NULL)
1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return 0;
1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else
1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      tmp = ARC_TOKEN_PTR(arc_token_list, atoken->first_next_arc);
1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* handle single epsilons */
1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (tmp->ilabel == WORD_EPSILON_LABEL && tmp->next_token_index == ARC_TOKEN_NULL)
1424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      tmp = ARC_TOKEN_PTR(arc_token_list, tmp->first_next_arc);
1434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (; tmp; tmp = ARC_TOKEN_PTR(arc_token_list, tmp->next_token_index))
1444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_DETAILS
1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      printf(" W%d(%s)", tmp->ilabel, tmp->ilabel != MAXwordID ? wmap->words[tmp->ilabel] : "");
1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
1484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (tmp->ilabel == word)
1494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
1504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_DETAILS
1514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        printf("\n");
1524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
1534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return tmp;
1544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
1554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      else if (tmp->ilabel < wmap->num_slots)
1564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
1574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (wordmap_whether_in_rule(wmap, word, tmp->ilabel))
1584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          return tmp;
1594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
1604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_DETAILS
1624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    printf("\n");
1634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
1644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return 0;
1654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectarc_token* get_arc_for_word_without_slot_annotation(arc_token* atoken, const char* word,
1694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    void* context_void,
1704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    wordID terminal_word)
1714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
1724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  srec_context* context = (srec_context*)context_void;
1734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  arc_token* arc_token_list = context->arc_token_list;
1744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  arc_token* tmp;
1754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  wordmap* wmap = context->olabels;
1764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  wordID wdid = wordmap_find_index(wmap, word);
1774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (atoken == ARC_TOKEN_ONE)
1794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
1804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* log_report("Warning:  bad thing is happening word=%d\n", word); */
1814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return 0;
1824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  else if (atoken == NULL)
1844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
1854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    arc_token root_arc;
1864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    root_arc.first_next_arc = ARC_TOKEN_LNK(arc_token_list, 0);
1874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    root_arc.next_token_index = ARC_TOKEN_NULL;
1884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    root_arc.ilabel = root_arc.olabel = 0;
1894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return get_arc_for_word_without_slot_annotation(&root_arc, word, context_void, terminal_word);
1904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  else if (word == NULL)
1924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
1934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* -pau- LABEL, the word graph does not seem to have them! */
1944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    tmp = ARC_TOKEN_PTR(arc_token_list, atoken->first_next_arc);
1954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!tmp)
1964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return ARC_TOKEN_ONE;
1974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else if (!tmp->first_next_arc && (tmp->ilabel == MAXwordID || tmp->ilabel == terminal_word))
1984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return ARC_TOKEN_ONE;
1994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else
2004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
2014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      /* again more weirdness in the output graph format1
2024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      might be due to multiple endnodes? */
2034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      for (tmp = ARC_TOKEN_PTR(arc_token_list, atoken->first_next_arc); tmp;
2044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project           tmp = ARC_TOKEN_PTR(arc_token_list, tmp->next_token_index))
2054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (tmp->ilabel == MAXwordID && tmp->first_next_arc == ARC_TOKEN_NULL)
2064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          return ARC_TOKEN_ONE;
2074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return 0;
2084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  else
2114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
2124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (tmp = ARC_TOKEN_PTR(arc_token_list, atoken->first_next_arc); tmp;
2134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         tmp = ARC_TOKEN_PTR(arc_token_list, tmp->next_token_index))
2144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
2154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (tmp->ilabel == wdid)
2164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
2174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return tmp;
2184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
2194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      else if (tmp->ilabel < wmap->num_slots)
2204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
2214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        wdid = wordmap_find_index_in_rule(wmap, word, tmp->ilabel);
2224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (wdid != MAXwordID)
2234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          return tmp;
2244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
2254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      else if (tmp->ilabel == WORD_EPSILON_LABEL)
2264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
2274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        tmp = ARC_TOKEN_PTR(arc_token_list, tmp->first_next_arc);
2284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        tmp = get_arc_for_word_without_slot_annotation(tmp, word, context_void, terminal_word);
2294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (tmp) return tmp;
2304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
2314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return 0;
2334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
2354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* protos */
2374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG_PARP_MANAGEMENT
2384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid list_free_parps(AstarStack* stack, char* msg);
2394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#else
2404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define list_free_parps(stack,msg)
2414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
2424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid print_partial_paths(partial_path** parps, int num_parps, srec* rec, const char* msg);
2444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid print_path(partial_path* path, srec* rec, char* msg);
2454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid sort_partial_paths(partial_path** parps, int num_parps);
2464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid insert_partial_path(partial_path** parps, int *pnum_parps,
2474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                         partial_path* insert_parp);
2484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectpartial_path* make_new_partial_path(AstarStack* stack);
2494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*void free_partial_path(AstarStack* stack, partial_path* parp); put the proto in astar.h */
2504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* functions */
2524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid append_arc_arriving(partial_path* path, partial_path* prev_path)
2544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
2554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  partial_path** pprev;
2564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (pprev = &path->first_prev_arc; (*pprev); pprev = &(*pprev)->linkl_prev_arc)
2574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ASSERT(*pprev != prev_path);
2584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  *pprev = prev_path;
2594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG_PARP_MANAGEMENT
2604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (1)
2614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
2624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int i, j;
2634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    partial_path* path_list[256], *k;
2644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    memset(path_list, 0, sizeof(partial_path*)*32);
2654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (i = 0, k = path->first_prev_arc; k; k = k->linkl_prev_arc)
2664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
2674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      for (j = 0; j < i; j++)
2684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (k == path_list[j])
2694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          ASSERT(0);
2704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      path_list[i++] = k;
2714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
2744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
2754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic void remove_path_arriving(partial_path* path, partial_path* prev_path)
2774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
2784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  partial_path** pprev;
2794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (!path) return;
2804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (pprev = &path->first_prev_arc; (*pprev); pprev = &(*pprev)->linkl_prev_arc)
2814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (*pprev == prev_path)
2824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
2834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      *pprev = (*pprev)->linkl_prev_arc;
2844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return;
2854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(0);
2874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
2884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectpartial_path* extend_path(AstarStack* stack,
2904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                          partial_path* parp,
2914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                          wtokenID extend_token_index,
2924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                          arc_token* arc_for_extend_token_index,
2934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                          bigcostdata max_cost,
2944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                          word_token* word_token_array,
2954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                          int* pwhether_complete)
2964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
2974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  asr_int32_t netcost;
2984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  partial_path* extended_parp;
2994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  word_token* wtoken;
3004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  costdata best_cost_for_node;
3014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  wtokenID best_extend_token;
3024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  partial_path* alt_extension;
3034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int sanity_count;
3044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  wtoken = &word_token_array[ extend_token_index];
3064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (wtoken->end_time > word_token_array[parp->token_index].end_time)
3084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
3094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* 20030921: this should never happen but we keep it for stop gap */
3104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* why does it happen: when in srec_process_word_boundary() we
3114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       occasionally kill_fsm_nodes_for_word_backtrace() but we did not kill the
3124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       stokens for this backtrace, neither did we kill the altword_tokens.  it
3134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       would just take too long to go through all of them, and so occasionally
3144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       there may leak some bad backtraces */
3154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return 0;
3164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* finding the netcost of this path extension */
3194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  best_extend_token = word_token_array[ parp->token_index].backtrace;
3204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  best_cost_for_node = word_token_array[ best_extend_token].cost;
3214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  wtoken = &word_token_array[ extend_token_index];
3224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(word_token_array[best_extend_token].end_time ==
3234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         word_token_array[extend_token_index].end_time);
3244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  netcost = wtoken->cost - best_cost_for_node;
3254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* ASSERT( netcost > 0); bug: sometimes this fails! fix: just use int32 */
3264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (netcost + parp->costsofar > max_cost)
3274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
3284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_DETAILS
3294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    printf("netcost %d (%d+%d) + parp->costsofar > max_cost %d\n",
3304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project           netcost, wtoken->cost, best_cost_for_node, parp->costsofar, max_cost);
3314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
3324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return 0;
3334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* check if we have a similar thing already extended */
3364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  sanity_count = 0;
3374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (alt_extension = parp->first_prev_arc; alt_extension;
3384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       alt_extension = alt_extension->linkl_prev_arc)
3394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
3404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    wtokenID alt_token_index = alt_extension->token_index;
3414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    wtokenID alt_bt_token_index;
3424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    wtokenID bt_token_index;
3434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    word_token* alt_wtoken;
3444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int join_frame_diff; /* need a signed frameID */
3454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ASSERT(sanity_count++ < 30);
3474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (alt_token_index == MAXwtokenID)
3484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      continue;
3494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    alt_wtoken = &word_token_array[alt_token_index];
3504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (alt_wtoken->word != wtoken->word)
3514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      continue;
3524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    alt_bt_token_index = alt_wtoken->backtrace;
3544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    bt_token_index = wtoken->backtrace;
3554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (alt_bt_token_index == MAXwtokenID && bt_token_index != MAXwtokenID)
3564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      continue;
3574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else if (alt_bt_token_index != MAXwtokenID && bt_token_index == MAXwtokenID)
3584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      continue;
3594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else if (alt_bt_token_index != MAXwtokenID && bt_token_index != MAXwtokenID)
3604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
3614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      word_token* alt_wtoken_bt;
3624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      word_token* wtoken_bt;
3634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      alt_wtoken_bt = &word_token_array[ alt_wtoken->backtrace];
3644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      wtoken_bt = &word_token_array[ wtoken->backtrace];
3654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (alt_wtoken_bt->word != wtoken_bt->word)
3664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        continue;
3674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
3684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    join_frame_diff = alt_wtoken->end_time - wtoken->end_time;
3704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (join_frame_diff < 0) join_frame_diff = -join_frame_diff;
3714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (join_frame_diff > 5)
3724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      continue;
3734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* the proposed extension is similar in "all" ways to an existing
3754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       extension, so let's not make this new extension */
3764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_DETAILS
3774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    printf("proposed extension already done elsewhere\n");
3784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
3794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return 0;
3804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* this is a TRUE new extension, so let's extend for sure */
3834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  extended_parp = make_new_partial_path(stack);
3844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (!extended_parp)
3854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
3864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_DETAILS
3874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    printf("make_new_partial_path returned 0\n");
3884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
3894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return 0;
3904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  extended_parp->costsofar = parp->costsofar + netcost;
3924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  extended_parp->token_index = extend_token_index;
3934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (extend_token_index != MAXwtokenID)
3944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    extended_parp->word = word_token_array[ extend_token_index].word;
3954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  else
3964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    extended_parp->word = MAXwordID;
3974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (wtoken->backtrace == MAXwtokenID)
3984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
3994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    *pwhether_complete = 1;
4004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    extended_parp->first_prev_arc = PARP_TERMINAL;
4014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
4024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  else
4034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
4044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    *pwhether_complete = 0;
4054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
4064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  extended_parp->arc_for_wtoken = arc_for_extend_token_index;
4074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  extended_parp->refcount = 1;
4094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  parp->refcount++;
4104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* maintain the parp tree */
4124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  extended_parp->next = parp;
4134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  append_arc_arriving(parp, extended_parp);
4144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_DETAILS
4154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  printf("extend path returned %x\n", extended_parp);
4164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
4174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return extended_parp;
4194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
4204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid check_stack_root_sanity(AstarStack* stack)
4224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
4234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  partial_path* parp1 = stack->root_path;
4244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* append_arc_arriving(stack->root_path, parp); */
4254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (; parp1->linkl_prev_arc != NULL; parp1 = parp1->linkl_prev_arc)
4264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ASSERT(parp1 != parp1->linkl_prev_arc);
4274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
4284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*
4304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * make a blank partial path, free one if necessary
4314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */
4324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectpartial_path* make_new_partial_path(AstarStack* stack)
4344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
4354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  partial_path* return_parp = stack->free_parp_list;
4364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (return_parp)
4374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
4384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    stack->free_parp_list = return_parp->next;
4394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    memset((void*)return_parp, 0, sizeof(*return_parp)); /* needed */
4404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
4414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  else
4424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
4434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    log_report("Warning: ran out of partial_paths, reprune\n");
4444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_DETAILS
4454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    printf("Warning: ran out of partial_paths, reprune\n");
4464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
4474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* kill the last one, and return it, this may free more than one parp! */
4484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (stack->num_active_paths == 0)
4494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return 0;
4504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    stack->num_active_paths--;
4514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return_parp = stack->active_paths[stack->num_active_paths];
4524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    hash_del((FixedSizeHash*)stack->pphash, return_parp);
4534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    free_partial_path(stack, return_parp);
4544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return_parp = stack->free_parp_list;
4554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    stack->free_parp_list = return_parp->next;
4564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    memset((void*)return_parp, 0, sizeof(*return_parp)); /* needed */
4574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
4584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return return_parp;
4594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
4604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* free_partial_path
4624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project   frees the path that was passed in, and also any backpointers.
4634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project   refcount counts the number of parps that depend on this parp */
4644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid free_partial_path(AstarStack* stack, partial_path* parp)
4654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
4664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  partial_path* next_parp;
4674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (; parp; parp = next_parp)
4684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
4694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    next_parp = parp->next;
4704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    parp->refcount--;
4714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (parp->refcount == 0)
4724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {    /* first time around this always passes */
4734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      remove_path_arriving(parp->next, parp);
4744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      parp->next = stack->free_parp_list;
4754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      stack->free_parp_list = parp;
4764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
4774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else break;
4784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
4794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
4804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*
4824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * make a partial path from a single word at the very end of the graph
4834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */
4844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectpartial_path* make_partial_path(AstarStack* stack,
4864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                wtokenID token_index, srec* rec,
4874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                int* pwhether_complete)
4884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
4894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  partial_path* parp;
4904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  word_token* wtoken;
4914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* todo: replace this with partial_path_tokens! */
4934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  parp = make_new_partial_path(stack);
4944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (!parp) return parp;
4954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  wtoken = &rec->word_token_array[token_index];
4974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  parp->token_index = token_index;
4984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (token_index != MAXwtokenID)
4994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    parp->word = rec->word_token_array[ token_index].word;
5004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  else
5014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    parp->word = MAXwordID;
5024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* wtoken->end_time should be equal to rec->current_search_frame */
5034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(rec->accumulated_cost_offset[ wtoken->end_time] != 0);
5044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  parp->costsofar = rec->accumulated_cost_offset[ wtoken->end_time];
5054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  parp->costsofar += wtoken->cost;
5064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* BKWD: rec->word_token_array[ wtoken->backtrace].cost + acc[] */
5074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* FRWD: wtoken->cost + acc[] - rec->word_token_array[ wtoken->backtrace].cost + acc[] */
5084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  parp->next = 0;
5094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  parp->first_prev_arc = parp->linkl_prev_arc = 0;
5104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (wtoken->backtrace == MAXwtokenID)
5114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    *pwhether_complete = 1;
5124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  else
5134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    *pwhether_complete = 0;
5144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  parp->arc_for_wtoken = 0;
5154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  parp->refcount = 1;
5164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return parp;
5174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
5184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* initialize astar search */
5204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectAstarStack* astar_stack_make(srec* rec, int max_nbest_len)
5224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
5234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int i;
5244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  AstarStack *stack;
5254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* allocations */
5274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack = (AstarStack*)CALLOC_CLR(1, sizeof(AstarStack), "search.astar.base");
5284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->max_active_paths = max_nbest_len + NBEST_LEN_MARGIN * 3;
5294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->max_complete_paths = max_nbest_len + NBEST_LEN_MARGIN;
5304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->complete_paths = (partial_path**)CALLOC_CLR(stack->max_complete_paths, sizeof(partial_path*), "search.astar.cplist");
5314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->complete_path_confidences = (int*)CALLOC_CLR(stack->max_complete_paths, sizeof(int), "search.astar.confvalues");
5324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->active_paths = (partial_path**)CALLOC_CLR(stack->max_active_paths, sizeof(partial_path*), "search.astar.aplist");
5334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->prune_delta = ASTAR_PRUNE_DELTA;
5344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->num_complete_paths = 0;
5364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->num_active_paths = 0;
5374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->partial_path_array = (partial_path*)CALLOC_CLR(MAX_NUM_PARPS, sizeof(stack->partial_path_array[0]), "search.astar.pparray");
5394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->partial_path_array_size = MAX_NUM_PARPS;
5404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->free_parp_list = &stack->partial_path_array[0];
5424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (i = 1; i < MAX_NUM_PARPS; i++)
5434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
5444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    stack->partial_path_array[i-1].next = &stack->partial_path_array[i];
5454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
5464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->partial_path_array[i-1].next = 0;
5474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->root_path = 0;
5484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->pphash = (void*)CALLOC_CLR(1, sizeof(FixedSizeHash), "search.astar.pphash");
5504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  astar_stack_clear(stack);
5514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return stack;
5524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
5534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint astar_stack_destroy(srec* rec)
5554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
5564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  AstarStack *stack = rec->astar_stack;
5574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  FREE(stack->active_paths);
5584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  FREE(stack->complete_paths);
5594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  FREE(stack->complete_path_confidences);
5604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  FREE(stack->partial_path_array);
5614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  FREE(stack->pphash);
5624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  FREE(stack);
5634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  rec->astar_stack = 0;
5644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return 0;
5654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
5664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* prepares for astar after forward search on an utterance */
5684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint astar_stack_prepare(AstarStack* stack, int request_nbest_len, srec* rec)
5704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
5714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  wtokenID token_index;
5724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  word_token* wtoken;
5734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  partial_path* parp;
5744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int whether_complete;
5754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  frameID end_frame = rec->current_search_frame;
5764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int num_wordends;
5774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  list_free_parps(stack, "astar_stack_prepare ");
5794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->num_active_paths = 0;
5814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->num_complete_paths = 0;
5824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->root_path = make_new_partial_path(stack);
5844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(stack->root_path);
5854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->root_path->refcount = 9999;
5864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->root_path->token_index = MAXwtokenID;
5874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->root_path->word = MAXwordID;
5884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  num_wordends = 0;
5904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (token_index = rec->word_lattice->words_for_frame[end_frame];
5914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       token_index != MAXwtokenID;
5924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       token_index = wtoken->next_token_index)
5934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
5944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    num_wordends++;
5954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    wtoken = &rec->word_token_array[ token_index];
5964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    parp = make_partial_path(stack, token_index, rec, &whether_complete);
5974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!parp)
5984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
5994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      log_report("Error: out-of-memory in astar_stack_prepare(), "
6004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                 "num_wordends %d\n", num_wordends);
6014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      stack->num_complete_paths = 0;
6024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return 1;
6034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
6044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    append_arc_arriving(stack->root_path, parp);
6054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (parp && whether_complete)
6074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
6084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      /* here .. check for dups ?? */
6094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      stack->complete_paths[ stack->num_complete_paths++] = parp;
6104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (stack->num_complete_paths == request_nbest_len)
6114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return 0;
6124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
6134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else if (parp)
6144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
6154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      stack->active_paths[ stack->num_active_paths++] = parp;
6164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
6174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
6184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  list_free_parps(stack, "astar_stack_prepare ");
6204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return 0;
6224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
6234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* cleans up astar after an utterance */
6254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid astar_stack_clear(AstarStack* stack)
6274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
6284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int i;
6294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* free the partial_path's that were allocated */
6314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (i = 0; i < stack->num_active_paths; i++)
6324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    free_partial_path(stack, stack->active_paths[i]);
6334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (i = 0; i < stack->num_complete_paths; i++)
6344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    free_partial_path(stack, stack->complete_paths[i]);
6354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (stack->root_path)
6364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    free_partial_path(stack, stack->root_path);
6374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* this shouldn't be necessary, but there are a couple of bugs
6394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project     in parp management, so let's leave it for now */
6404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->free_parp_list = &stack->partial_path_array[0];
6414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (i = 1; i < MAX_NUM_PARPS; i++)
6424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    stack->partial_path_array[i-1].next = &stack->partial_path_array[i];
6434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->partial_path_array[i-1].next = 0;
6444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->num_active_paths = 0;
6454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->num_complete_paths = 0;
6464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->root_path = 0;
6474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  list_free_parps(stack, "astar_stack_clear ");
6494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
6514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* do the astar search */
6534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint astar_stack_do_backwards_search(srec* rec, int request_nbest_len)
6554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
6564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int i;
6574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  AstarStack *stack = rec->astar_stack;
6584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  word_token *wtoken, *btoken;
6594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  partial_path *parp, *extended_parp, *tparp;
6604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  wtokenID token_index, btoken_index;
6614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int whether_complete = 0;
6624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  bigcostdata max_cost = 0;
6634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  arc_token* arc_for_token_index = NULL;
6644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  arc_token* arc_token_list;   /* to skip graph constraints, just set this to NULL */
6664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  arcID arc_token_list_len;
6674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  srec_word_lattice* lattice;
6684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int max_complete_paths;
6704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (!rec || !rec->context)
6724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
6734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    log_report("Error: bad arguments in astar_stack_do_backwards_search()\n");
6744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return 1;
6754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
6764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  max_complete_paths = request_nbest_len < stack->max_complete_paths ?
6774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                       request_nbest_len : stack->max_complete_paths;
6784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  arc_token_list = rec->context->arc_token_list;
6804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  arc_token_list_len = rec->context->arc_token_list_len;
6814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  lattice = rec->word_lattice;
6824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* initialization, now from calling function */
6844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* astar_stack_prepare(stack, request_nbest_len, rec); */
6854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  hash_init((FixedSizeHash*)stack->pphash, rec);
6864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* search */
6884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  while (stack->num_active_paths > 0)
6894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
6904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    list_free_parps(stack, "do_astar_back BEG");
6924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* extend top path */
6944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    parp = stack->active_paths[0];
6954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    wtoken = &rec->word_token_array[parp->token_index];
6964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    token_index = wtoken->backtrace;
6974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    wtoken = &rec->word_token_array[token_index];
6984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ASSERT(token_index != MAXwtokenID); /* should have been "complete" */
6994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_DETAILS
7024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    print_partial_paths(stack->complete_paths, stack->num_complete_paths,
7034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        rec, "=== Complete Paths ===\n");
7044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    print_partial_paths(stack->active_paths, stack->num_active_paths,
7054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        rec, "=== Active Paths ===\n");
7064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
7074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* pop this one */
7094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (i = 0; i < stack->num_active_paths - 1; i++)
7104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      stack->active_paths[i] = stack->active_paths[i+1];
7114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    stack->num_active_paths--;
7124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (wtoken->end_time != MAXframeID)
7144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
7154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      /* sort the word token array by score, so that we pick the best
7164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      scoring paths first */
7174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      /* later add a 'whether_sorted' flag to the lattice_at_frame information */
7184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      sort_word_lattice_at_frame(rec, (frameID)(wtoken->end_time + 1));
7194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      /* extend this path, with every word ending where this word began */
7214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      /* #warning there appear to be duplicates */
7224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      btoken_index = lattice->words_for_frame[ wtoken->end_time+1];
7244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
7254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else
7264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
7274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      btoken_index = MAXwtokenID;
7284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
7294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_DETAILS
7314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    print_path(parp, rec, "Now Processing Top of Stack(2): ");
7324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    printf("Frame %d\n", wtoken->end_time + 1);
7334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    print_word_token_list(rec, btoken_index, "List of Word at Frame\n");
7344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
7354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (; btoken_index != MAXwtokenID; btoken_index = btoken->next_token_index)
7374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
7384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      btoken = &rec->word_token_array[btoken_index];
7394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      /* alternate choice must end at same frame */
7414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      //      ASSERT(btoken->end_time == wtoken->end_time);
7424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_DETAILS
7444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      print_path(parp, rec, "Now Processing Top of Stack(3): ");
7454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      print_word_token(rec, btoken_index, "Extending word ");
7464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
7474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      /* check if this potential extension is allowed by the
7494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      word graph, if not just drop it! */
7504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (arc_token_list)
7524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
7534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        arc_for_token_index = get_arc_for_word(parp->arc_for_wtoken,
7544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                               btoken->word,
7554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                               rec->context,
7564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                               rec->context->beg_silence_word);
7574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (arc_for_token_index == NULL)
7584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
7594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_DETAILS
7604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          printf("Not allowed by graph!\n");
7614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
7624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          continue;
7634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
7644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
7654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      /* figure out the cost to beat ! */
7674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (stack->num_complete_paths)
7684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
7694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        max_cost = stack->complete_paths[0]->costsofar + stack->prune_delta;
7704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
7714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      else if (stack->num_active_paths == stack->max_active_paths)
7724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
7734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        max_cost = stack->active_paths[ stack->num_active_paths-1]->costsofar;
7744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
7754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      else if (stack->num_active_paths > 0)
7764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
7774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        max_cost = stack->active_paths[0]->costsofar + stack->prune_delta;
7784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
7794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      else
7804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
7814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        max_cost = MAXbcostdata;
7824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
7834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      extended_parp = extend_path(stack, parp, btoken_index, arc_for_token_index, max_cost, rec->word_token_array, &whether_complete);
7854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (extended_parp)
7874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
7884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        int fsh_rc = hash_set((FixedSizeHash*)stack->pphash, extended_parp);
7894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (fsh_rc == FSH_KEY_OCCUPIED)
7904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
7914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          /* seen this path before, let's not bother with it */
7924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_DETAILS
7934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          print_path(extended_parp, rec, "dup!! ");
7944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
7954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          free_partial_path(stack, extended_parp);
7964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          extended_parp = 0;
7974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
7984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
7994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
8004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (extended_parp && whether_complete)
8014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
8024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        ASSERT(stack->num_complete_paths < stack->max_complete_paths);
8034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        stack->complete_paths[ stack->num_complete_paths++] = extended_parp;
8044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        /*if(stack->num_complete_paths >= request_nbest_len)
8054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          return 0;*/
8064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
8074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
8084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_DETAILS
8094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        print_path(extended_parp, rec, "&&Extended, complete : ");
8104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
8114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
8124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      else if (extended_parp)
8134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
8144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        /* todo: check if this extended_parp is already completed on the
8154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project           stack->complete_paths, if so just rejoin with that guy somehow */
8164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
8174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_DETAILS
8184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        print_path(extended_parp, rec, "&&Extended, incomplete : ");
8194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
8204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (stack->num_active_paths == stack->max_active_paths)
8214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
8224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          /* kill the last one */
8234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          stack->num_active_paths--;
8244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          tparp = stack->active_paths[stack->num_active_paths];
8254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          hash_del((FixedSizeHash*)stack->pphash, tparp);
8264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          free_partial_path(stack, tparp);
8274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
8284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        insert_partial_path(stack->active_paths, &stack->num_active_paths,
8294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            extended_parp);
8304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
8314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_DETAILS
8324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      else
8334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
8344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        printf("&&Extended, cost too high (>%d):\n", max_cost);
8354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
8364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
8374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (stack->num_complete_paths == max_complete_paths)
8384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
8394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_DETAILS
8404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        printf("Complete paths are full %d, stopping\n", stack->num_complete_paths);
8414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
8424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        break;
8434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
8444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
8454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_DETAILS
8464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (do_draw_as_dotty > 0)
8474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
8484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      char tmp[32];
8494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      sprintf(tmp, "astar.%.3d.dot", do_draw_file_idx++);
8504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      astar_draw_tree_as_dotty(tmp, rec, stack);
8514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (do_draw_as_dotty > 1)
8524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        system("C:/tools/graphviz/bin/dotty.exe astar.dot");
8534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
8544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
8554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
8564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SREC_STATS_UPDATE_ASTAR(stack);
8574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    hash_del((FixedSizeHash*)stack->pphash, parp);
8584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    free_partial_path(stack, parp); /* done all extensions, now free */
8594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (stack->num_complete_paths == max_complete_paths)
8604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
8614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_DETAILS
8624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      printf("Complete paths are full %d, stopping\n", stack->num_complete_paths);
8634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
8644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      break;
8654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
8664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
8674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    list_free_parps(stack, "do_astar_back END");
8684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
8694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  sort_partial_paths(stack->complete_paths, stack->num_complete_paths);
8704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* if we're doing a search within a grammar, then print the complete choices
8714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project     else we're likely just doing reprune_word_tokens() */
8724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_SOMEWHAT
8734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (rec->context->arc_token_list)
8744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    print_partial_paths(stack->complete_paths, stack->num_complete_paths,
8754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        rec, "=== Complete paths ===\n");
8764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
8774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* now the caller must call clear */
8784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* astar_stack_clear(stack); */
8794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
8804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return 0;
8814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
8824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
8834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid sort_partial_paths(partial_path** parps, int num_parps)
8844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
8854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int i, j;
8864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (i = 0; i < num_parps; i++)
8874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
8884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (j = 0; j < num_parps - 1; j++)
8894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
8904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (parps[j]->costsofar > parps[j+1]->costsofar)
8914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
8924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        partial_path* parp = parps[j];
8934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        parps[j] = parps[j+1];
8944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        parps[j+1] = parp;
8954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
8964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
8974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
8984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
8994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
9004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid insert_partial_path(partial_path** parps, int *pnum_parps, partial_path* insert_parp)
9014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
9024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int i, j, insert_index;
9034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int num_parps = *pnum_parps;
9044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
9054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* maintain the list sorted, search the list linearly for now,
9064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project     do priority_q type heap later */
9074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  insert_index = num_parps;
9084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (i = 0; i < num_parps; i++)
9094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
9104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (insert_parp->costsofar < parps[i]->costsofar)
9114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
9124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      insert_index = i;
9134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      break;
9144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
9154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
9164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (j = num_parps; j > insert_index; --j)
9174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    parps[j] = parps[j-1];
9184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  parps[j] = insert_parp;
9194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  num_parps++;
9204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  *pnum_parps = num_parps;
9214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
9224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
9234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid print_path(partial_path* ipath, srec* rec, char* msg)
9244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
9254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  partial_path* path;
9264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  word_token* wtoken;
9274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  word_token* last_wtoken;
9284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  char* p;
9294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  char trans[256];
9304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int max_trans_len = 255;
9314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int rc;
9324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#ifndef NDEBUG
9334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int sanity_count = 0;
9344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
9354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  frameID end_time;
9364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
9374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  PLogMessage("%spath score=%d ", msg, ipath->costsofar);
9384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
9394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  rc = sprint_word_token_backtrace(trans, max_trans_len, rec, ipath->token_index);
9404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(rc == 0);
9414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
9424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  last_wtoken = 0;
9434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  end_time = (ipath && ipath->token_index != MAXwtokenID) ? rec->word_token_array[ipath->token_index].end_time : MAXframeID;
9444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if SHOW_END_TIMES
9454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  printf("%s@%d || ", trans, end_time);
9464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#else
9474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  printf("%s || ", trans);
9484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
9494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
9504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  path = ipath->next;  /* we've already printed this thing */
9514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (; path; path = path->next)
9524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
9534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ASSERT(sanity_count++ < 256);
9544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (path->token_index == MAXwtokenID) break;
9554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    wtoken = &rec->word_token_array[ path->token_index];
9564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    p = "NULL";
9574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (rec->context->olabels->words[wtoken->word])
9584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      p = rec->context->olabels->words[wtoken->word];
9594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if SHOW_END_TIMES
9604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    printf("%s@%d ", p, wtoken->end_time);
9614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#else
9624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    printf("%s ", p);
9634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
9644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (last_wtoken != NULL)
9654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
9664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (wtoken->end_time < last_wtoken->end_time)
9674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
9684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        printf(" Error: wt%d < lwt%d\n", wtoken->end_time, last_wtoken->end_time);
9694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        pfflush(PSTDOUT);
9704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        ASSERT(0);
9714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
9724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
9734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    last_wtoken = wtoken;
9744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
9754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  printf("\n");
9764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
9774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
9784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid print_partial_paths(partial_path** parps, int num_parps,
9794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                         srec* rec, const char* msg)
9804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
9814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int i;
9824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  char buf[32];
98335a6d12873c94f19efdf4763b7ed4f00212b1d15Nick Kralevich  printf("%s", msg);
9844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (i = 0; i < num_parps; i++)
9854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
9864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    sprintf(buf, "%.3d ", i);
9874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    print_path(parps[i], rec, buf);
9884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
9894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
9904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
9914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
9924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*--------------------------------------------------------------------------*
9934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                          *
9944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * visualization .. sometimes helps debugging                               *
9954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                          *
9964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *--------------------------------------------------------------------------*/
9974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
9984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_DETAILS
9994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
10004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
10014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint astar_draw_arc_as_dotty(FILE* fp, partial_path* parp, int src_node, int *nodes_used, srec* rec)
10024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
10034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  word_token* word_token_array = rec->word_token_array;
10044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  partial_path* parp1;
10054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int sanity_count = 0;
10064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int to_nodes[32], *pto_nodes, inode;
10074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  pto_nodes = to_nodes;
10084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
10094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  fprintf(fp, "%d [label = \"%d\", shape = circle, style = solid]\n",
10104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          src_node, src_node);
10114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (parp1 = parp->first_prev_arc; parp1; parp1 = parp1->linkl_prev_arc)
10124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
10134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    arc_token* arc = parp1->arc_for_wtoken;
10144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (inode = 0; nodes_used[inode]; inode++) ;
10154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    nodes_used[inode] = 1;
10164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    *pto_nodes++ = inode;
10174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    fprintf(fp, "  %d -> %d [label = \"(%d).%d.%s@%d/%d\"];\n",
10184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            src_node, inode, parp1->refcount,
10194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            parp1->token_index,
10204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            (arc && arc != (arc_token*)1) ? rec->context->olabels->words[arc->ilabel] : "NULL",
10214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            word_token_array[ parp1->token_index].end_time,
10224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            parp1->costsofar);
10234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (sanity_count++  > 30) break;
10244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
10254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
10264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  pto_nodes = to_nodes;
10274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  sanity_count = 0;
10284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (parp1 = parp->first_prev_arc; parp1; parp1 = parp1->linkl_prev_arc)
10294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
10304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    astar_draw_arc_as_dotty(fp, parp1, *pto_nodes, nodes_used, rec);
10314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    pto_nodes++;
10324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (sanity_count++  > 30) break;
10334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
10344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return 0;
10354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
10364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
10374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint astar_draw_tree_as_dotty(const char* file, srec* rec, AstarStack* stack)
10384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
10394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  word_token* word_token_array = rec->word_token_array;
10404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  FILE* fp = fopen(file, "w");
10414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  partial_path* parp;
10424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int nodes_used[1024];
10434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  memset(nodes_used, 0, 1024*sizeof(int));
10444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
10454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  fprintf(fp,
10464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          "digraph FSM {\n"
10474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          "rankdir = LR;\n"
10484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          "size = \"8.5,11\";\n"
10494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          "fontsize = 14;\n"
10504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          "label = \"\\n\\naaron.PCLG\"\n"
10514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          "center = 1;\n"
10524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          "orientation = Landscape\n"
10534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         );
10544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  nodes_used[0] = 1;
10554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (parp = stack->root_path; parp; parp = parp->linkl_prev_arc)
10564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    astar_draw_arc_as_dotty(fp, parp, 0, nodes_used, rec);
10574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
10584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  fprintf(fp, "}\n");
10594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  fclose(fp);
10604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  printf("....... dotty %s ......\n", file);
10614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return 0;
10624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
10634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
10644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
10654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
10664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*--------------------------------------------------------------------------*
10674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                          *
10684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * functions relating to in-recognition backtrace                           *
10694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                          *
10704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *--------------------------------------------------------------------------*/
10714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
10724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint maybe_add_to_active_paths(AstarStack* stack, word_token* word_token_array, bigcostdata cost, wtokenID wtoken_index);
10734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint astar_stack_prepare_from_active_search(AstarStack* stack, int nbestlen, srec* rec)
10744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
10754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  wtokenID wtoken_index;
10764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ftokenID ftoken_index;
10774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  fsmnode_token* ftoken;
10784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stokenID stoken_index;
10794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  fsmarc_token* stoken;
10804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* word_token* wtoken; */
10814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  frameID prune_frame = rec->current_search_frame;
10824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int i, rc = 0, rc1 = 0;
10834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  bigcostdata parp_costsofar;
10844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
10854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->num_active_paths = 0;
10864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->num_complete_paths = 0;
10874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->root_path = 0;
10884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
10894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* put it on the stack */
10904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->root_path = make_new_partial_path(stack);
10914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(stack->root_path);
10924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->root_path->refcount = 9999;
10934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->root_path->token_index = MAXwtokenID;
10944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->root_path->word = MAXwordID;
10954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
10964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ftoken_index = rec->active_fsmnode_tokens;
10974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (; ftoken_index != MAXftokenID; ftoken_index = ftoken->next_token_index)
10984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
10994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ftoken = &rec->fsmnode_token_array[ ftoken_index];
11004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    wtoken_index = ftoken->word_backtrace;
11014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (wtoken_index == MAXwtokenID)
11024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      continue;
11034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
11044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* fix the score */
11054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    parp_costsofar = ftoken->cost;
11064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    parp_costsofar += rec->accumulated_cost_offset[ prune_frame];
11074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
11084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    rc += (rc1 = maybe_add_to_active_paths(stack, rec->word_token_array, parp_costsofar, wtoken_index));
11094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* we can handle that a path was not added for this ftoken because
11104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       we made sure to flag the wtokens along it's top backtrace */
11114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
11124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
11134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stoken_index = rec->active_fsmarc_tokens;
11144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (; stoken_index != MAXstokenID; stoken_index = stoken->next_token_index)
11154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
11164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    stoken = &rec->fsmarc_token_array[ stoken_index];
11174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (i = 0; i < stoken->num_hmm_states; i++)
11184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
11194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      wtoken_index = stoken->word_backtrace[i];
11204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (wtoken_index == MAXwtokenID)
11214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        continue;
11224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      parp_costsofar = stoken->cost[i];
11234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      parp_costsofar += rec->accumulated_cost_offset[ prune_frame];
11244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
11254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      rc += (rc1 = maybe_add_to_active_paths(stack, rec->word_token_array, parp_costsofar, wtoken_index));
11264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      /* we can handle that a path was not added for this stoken because
11274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      we made sure to flag the wtokens along it's top backtrace */
11284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
11294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
11304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
11314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_DETAILS
11324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  print_partial_paths(stack->active_paths, stack->num_active_paths,
11334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                      rec, "== active paths before sorting ==\n");
11344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  sort_partial_paths(stack->active_paths, stack->num_active_paths);
11354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  print_partial_paths(stack->active_paths, stack->num_active_paths,
11364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                      rec, "== active paths after sorting ==\n");
11374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
11384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  list_free_parps(stack, "astar_prepare_from_active_search");
11394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return 0;
11404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
11414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
11424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint maybe_add_to_active_paths(AstarStack* stack, word_token* word_token_array, bigcostdata parp_costsofar, wtokenID wtoken_index)
11434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
11444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int i;
11454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int replace_index;
11464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int inserts_index;
11474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  partial_path* parp;
11484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  word_token* wtoken;
11494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  wtoken = &word_token_array[ wtoken_index];
11504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
11514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (wtoken->backtrace == MAXwtokenID)
11524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
11534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return 0;
11544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
11554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
11564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* see if we already have this word token backtrace */
11574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  replace_index = -1;
11584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  inserts_index = -1;
11594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (i = 0; i < stack->num_active_paths; i++)
11604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
11614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (stack->active_paths[i]->token_index == wtoken_index)
11624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
11634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (parp_costsofar < stack->active_paths[i]->costsofar)
11644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
11654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        /* this one is better than another we already have! */
11664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        replace_index = i;
11674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (inserts_index < 0)
11684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          inserts_index = i;
11694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
11704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      break;
11714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
11724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else if (parp_costsofar < stack->active_paths[i]->costsofar)
11734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
11744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (inserts_index < 0)
11754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        inserts_index = i;
11764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
11774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
11784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_QBT_DETAILS
11794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  printf("maybe_add replace %d insert %d\n", replace_index, inserts_index);
11804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
11814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
11824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (replace_index >= 0)
11834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
11844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    free_partial_path(stack, stack->active_paths[replace_index]);
11854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* stack->active_paths[replace_index] = 0; */
11864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (i = replace_index; i > inserts_index; --i)
11874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      stack->active_paths[i] = stack->active_paths[i-1];
11884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    stack->active_paths[inserts_index] = 0;
11894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
11904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  else if (inserts_index >= 0)
11914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
11924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (stack->num_active_paths == stack->max_active_paths)
11934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
11944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      free_partial_path(stack, stack->active_paths[ stack->num_active_paths-1]);
11954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      stack->num_active_paths--;
11964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
11974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (i = stack->num_active_paths; i > inserts_index; --i)
11984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      stack->active_paths[i] = stack->active_paths[i-1];
11994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    stack->active_paths[inserts_index] = 0;
12004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    stack->num_active_paths++;
12014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
12024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  else if (stack->num_active_paths < stack->max_active_paths)
12034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
12044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* append if there's space */
12054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    inserts_index = stack->num_active_paths;
12064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    stack->num_active_paths++;
12074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    stack->active_paths[inserts_index] = 0;
12084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
12094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  else
12104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
12114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* no space */
12124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return 1;
12134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
12144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
12154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* create a parp */
12164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_QBT_DETAILS
12174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  printf("maybe_add .. creating new parp %d\n", parp_costsofar);
12184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
12194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* this should always succeed because of above frees */
12204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(stack->free_parp_list);
12214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  parp = make_new_partial_path(stack);
12224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  parp->token_index = wtoken_index;
12234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (wtoken_index != MAXwtokenID)
12244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    parp->word = word_token_array[ wtoken_index].word;
12254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  else
12264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    parp->word = MAXwordID;
12274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  parp->next = stack->root_path;
12284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  parp->first_prev_arc = parp->linkl_prev_arc = 0;
12294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  parp->arc_for_wtoken = 0;
12304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  parp->refcount = 1;
12314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  parp->costsofar = parp_costsofar;
12324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
12334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  stack->active_paths[ inserts_index] = parp;
12344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
12354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_QBT_DETAILS
12364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  printf("maybe_add .. appending to root\n");
12374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
12384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  append_arc_arriving(stack->root_path, parp);
12394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return 0;
12404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
12414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
12424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
12434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint astar_stack_flag_word_tokens_used(AstarStack* stack, srec* rec)
12444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
12454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int i;
12464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  wtokenID wtoken_index;
12474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  partial_path* parp;
12484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int num_flagged_by_path;
12494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
12504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_QBT_DETAILS
12514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  print_partial_paths(stack->complete_paths, stack->num_complete_paths,
12524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                      rec, "=== Complete QBT paths ===\n");
12534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
12544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
12554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (i = 0; i < stack->num_complete_paths; i++)
12564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
12574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    num_flagged_by_path = 0;
12584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (parp = stack->complete_paths[i]; parp; parp = parp->next)
12594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
12604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      wtoken_index = parp->token_index;
12614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (wtoken_index == MAXwtokenID) break;
12624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      rec->word_token_array_flags[ wtoken_index]++;
12634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (rec->word_token_array_flags[wtoken_index] > 0)
12644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
12654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        num_flagged_by_path++;
12664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_QBT_DETAILS
12674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        printf("%d ", wtoken_index);
12684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
12694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
12704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
12714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
12724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* also flag the main backtrace of every word token */
12734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* we do we need this?  I'm not sure, but it appears
12744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       that some backtrace tokens are not flagged for whatever
12754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       reason.  It's worth revisiting this when other bugs are
12764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       are resolved.  This is in a separate loop from the
12774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       above because it allows us to detect that this is
12784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       happening in the first place */
12794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (parp = stack->complete_paths[i]; parp; parp = parp->next)
12804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
12814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      word_token *btoken, *last_btoken;
12824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      wtokenID btoken_index;
12834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      wtoken_index = parp->token_index;
12844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (wtoken_index == MAXwtokenID) break;
12854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      last_btoken = NULL;
12864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      btoken = &rec->word_token_array[ wtoken_index];
12874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      btoken_index = btoken->backtrace;
12884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      for (; btoken_index != MAXwtokenID; btoken_index = btoken->backtrace)
12894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
12904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        btoken = &rec->word_token_array[ btoken_index];
12914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        rec->word_token_array_flags[ btoken_index]++;
12924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (rec->word_token_array_flags[ btoken_index] == 1)
12934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
12944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          num_flagged_by_path++;
12954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_QBT_DETAILS
12964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          printf("%db ", btoken_index);
12974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
12984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
12994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (last_btoken && last_btoken->end_time <= btoken->end_time)
13004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
13014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          PLogError("bad looping path encountered, breaking");
13024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          break;
13034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
13044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        last_btoken = btoken;
13054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
13064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
13074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
13084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if PRINT_ASTAR_QBT_DETAILS
13094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    printf("complete path %.3d flagged %d\n", i, num_flagged_by_path);
13104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
13114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
13124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return 0;
13134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
13144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
13154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
13164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG_PARP_MANAGEMENT
13174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define PARP_FREE 1
13184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define PARP_USED 2
13194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid list_free_parps(AstarStack* stack, char* msg)
13204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
13214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  partial_path* parp;
13224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int i, num = 0;
13234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  char x[MAX_NUM_PARPS];
13244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (i = 0; i < MAX_NUM_PARPS; i++) x[i] = 0;
13254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (parp = stack->free_parp_list; parp; parp = parp->next)
13264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
13274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    num++;
13284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    x[(parp-stack->partial_path_array)] = PARP_FREE;
13294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
13304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  PLogMessage("%sstack->free_parp_list size %d ", msg, num);
13314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  PLogMessage("active %d complete %d\n", stack->num_active_paths, stack->num_complete_paths);
13324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
13334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (i = 0; i < stack->num_active_paths; i++)
13344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
13354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    parp = stack->active_paths[i];
13364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (; parp; parp = parp->next) x[(parp-stack->partial_path_array)] = PARP_USED;
13374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
13384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (i = 0; i < stack->num_complete_paths; i++)
13394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
13404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    parp = stack->complete_paths[i];
13414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (; parp; parp = parp->next) x[(parp-stack->partial_path_array)] = PARP_USED;
13424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
13434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (stack->root_path)
13444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    x[(stack->root_path-stack->partial_path_array)] = PARP_USED;
13454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  printf("free: ");
13464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (i = 0; i < MAX_NUM_PARPS; i++) if (x[i] == PARP_FREE) printf(" %d", i);
13474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  printf("\n");
13484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  printf("used: ");
13494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (i = 0; i < MAX_NUM_PARPS; i++) if (x[i] == PARP_USED) printf(" %d", i);
13504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  printf("\n");
13514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (i = 0, num = 0; i < MAX_NUM_PARPS; i++) if (!x[i]) num++;
13524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  printf("unaccounted for %d\n", num);
13534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(num == 0);
13544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
13554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
13564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
1357