// file: $isip/class/search/HierarchicalSearch/hsrch_14.cc // version: $Id: hsrch_14.cc 9742 2004-08-20 20:43:15Z may $ // // isip include files // #include "HierarchicalSearch.h" // method: printInstance // // arguments: // Instance* instance_a: (input) the instance to be printed // int32 level_num_a: (input) the search level // bool8 recursive_a: (input) recursive or not // // return: logical error status // // print instances // bool8 HierarchicalSearch::printInstance(Instance* new_instance_a, int32 level_num_a, bool8 recursive_a) { // lcoal variable // String val; String out; SearchSymbol start_sym; float32 old_score = 0.0; int32 old_frame = -1; SearchNode* old_node = (SearchNode*)NULL; Instance* old_instance = (Instance*)NULL; GraphVertex* old_vert = (GraphVertex*)NULL; Context* old_context = (Context*)NULL; bool8 recursive = true; int32 center = 0; // print level information // if ( level_num_a >= 0 ){ center = getSearchLevel(level_num_a).getRightContext() + 1; } old_instance = new_instance_a; while ( recursive ){ val.assign(L""); // old instance not NULL // if (old_instance != (Instance*)NULL) { // get current instance info // old_context = old_instance->getSymbol(); // get the current context length // int32 total_length = old_context->length(); // loop over all context symbols in current context, starting from // the oldest one // for (int32 i = total_length; i > 0; i--) { // get the i-th previous context symbol // old_vert = (GraphVertex*)(uint32)(*old_context)(-i); // central vertex is NULL // if ( old_vert == (GraphVertex*)NULL ){ start_sym.assign(L"_NULL_"); } // central vertex is not NULL // else { old_node = old_vert->getItem(); old_frame = old_instance->getFrame(); old_score = old_instance->getScore(); if ( old_node == &DiGraph::START_OBJ) { start_sym.assign(L"_START_"); } else if (old_node == &DiGraph::TERM_OBJ) { start_sym.assign(L"_TERM_"); } else { old_node->getSymbol(start_sym); } } val.concat(start_sym); // put in a form of b-oy+r // if ( i > 1 && i > center ){ val.concat(L"-"); } else if( i > 1 ){ val.concat(L"+"); } } // end of for loop } // old instance is not NULL // else old instance is a NULL // else{ start_sym.assign(L"NULL_INSTANCE"); val.concat(start_sym); } start_sym.assign(val); // print out the trace // out.concat(L"["); val.assign((int32)old_frame); out.concat(val); out.concat(L", "); out.concat(start_sym); out.concat(L", "); val.assign(old_score, L"%4.7f"); out.concat(val); out.concat(L", "); out.concat(old_instance); out.concat(L"]"); // change the flag for recursive // recursive = ( recursive_a && (old_instance != (Instance*)NULL) ) || (old_instance == new_instance_a); if ( recursive ){ if ( old_instance == new_instance_a ){ out.concat(L"<--"); } } else { // print level information // if ( level_num_a >= 0 ){ out.concat(L" ==> L"); val.assign(level_num_a); out.concat(val); } } if ( !(old_instance == new_instance_a) ){ Console::put(out); out.assign(L""); } if ( old_instance != (Instance*)NULL ){ old_instance = old_instance->getBackPointer(); } } //debug_level_d = Integral::NONE; // exit gracefully // return true; } // method: changeHistory // // arguments: // Instance*& curr_instance_a: (input) the instance that we want to change // bool8 ascend_a: (input) ascend or descend // int32 level_num_a: (input) current level // GraphVertex* start_vert_a : (input) lower level start vertex // // return: logical error status // // change the history of current instance // bool8 HierarchicalSearch::changeHistory(Instance*& curr_instance_a, bool8 ascend_a, int32 level_num_a, GraphVertex* start_vert_a){ // if going up - ascend // if ( ascend_a ){ curr_instance_a->setSymbol(context_pool_d.setLastAndAllocate(curr_instance_a->getSymbol(), (GraphVertex*)NULL)); ascend(curr_instance_a); } // if going down - descend // else { // if no preHistory, generate new context // if ((curr_instance_a->getSymbolStack() != (History*)NULL) && curr_instance_a->getSymbolStack()->isEmpty()) { // set the context length // int32 central_pos = getSearchLevel(level_num_a + 1).getRightContext() + 1; int32 left_context_length = getSearchLevel(level_num_a + 1).getLeftContext(); int32 total_context_length = left_context_length + central_pos; // error checking // if (getSearchLevel(level_num_a + 1).getLeftContext() != getSearchLevel(level_num_a + 1).getRightContext()) { return Error::handle(name(), L"changeHistory - left and right context lengths must be the same", Error::ARG, __FILE__, __LINE__); } // initialize left vertices of the context // Context new_context(total_context_length, central_pos); for (int32 i = 0; i < total_context_length; i++) { new_context.assignAndAdvance((uint64)start_vert_a); } // set current history // Context* symbol = context_pool_d.get(new_context); if (curr_instance_a->getSymbol() != (Context*)NULL) { curr_instance_a->setHistory(history_pool_d.pushAndAllocate(curr_instance_a->getHistory(), curr_instance_a->getSymbol())); } curr_instance_a->setSymbol(symbol); } // use preHistory // else{ descend(curr_instance_a); } } // exit // return true; } // method: addInstance // // arguments: // int32 level_num_a: (input) the level for which we will add instance // Instance*& curr_instance_a: (input) the current instance // Instance*& next_instance_a: (input) the next instance that we added // bool8 pruning_a: (input) do a pruning or not // // return: logical error status // // add the instance to a certain level // bool8 HierarchicalSearch::addInstance(int32 level_num_a, Instance*& curr_instance_a, Instance*& next_instance_a, bool8 pruning_a) { // local variable // float32 curr_score; GraphVertex* central_vertex = next_instance_a->getSymbol()->getCentralVertex(); if (central_vertex == (GraphVertex*)NULL ) { // can't pruning in this case // pruning_a = false; } else if (central_vertex->isStart()) { // can't pruning in this case // pruning_a = false; } // determine the symbol insertion penalty // if ((central_vertex != (GraphVertex*)NULL) && !(central_vertex->isStart()) && !(central_vertex->isTerm())) { int32 next_instance_level = central_vertex->getItem()->getSearchLevel()->getLevelIndex(); float32 symbol_penalty = getSearchLevel(next_instance_level).getSymbolPenalty(); int32 symbol_id = central_vertex->getItem()->getSymbolId(); // add the symbol insertion penalty if applicable // if (!getSearchLevel(next_instance_level).isDummySymbol(symbol_id) && !getSearchLevel(next_instance_level).isSPenaltyExcludeSymbol(symbol_id) && (central_vertex->getItem() != (SearchNode*)NULL)) { next_instance_a->setScore(next_instance_a->getScore() + symbol_penalty); } } // set the backpointer // next_instance_a->setBackPointer(curr_instance_a); // apply n-symbol score // applyNSymbolScore(next_instance_a, level_num_a); // if not pruning // if (!pruning_a || getSearchLevel(level_num_a).useSymbolGraph()) { curr_score = next_instance_a->getScore(); // update the maximal instance score for the beam pruning // if(getSearchLevel(level_num_a).useBeam() && (curr_score > max_instance_scores_d(level_num_a)) ) { max_instance_scores_d(level_num_a) = curr_score; } // add the instance to this level's instance list // instance_lists_d(level_num_a).insertLast(next_instance_a); // print debugging information // if (debug_level_d >= Integral::DETAILED) { // print the best instance // printInstance(next_instance_a, level_num_a); } // exit gracefully // return true; } // add the instance to the search node's instance list // Instance* existing_instance = (Instance*)NULL; SearchNode* next_node = next_instance_a->getSymbol()-> getCentralVertex()->getItem(); if (next_node->insertInstance(next_instance_a, current_frame_d, existing_instance)) { // add the instance to this level's instance list // instance_lists_d(level_num_a).insertLast(next_instance_a); // print debugging information // if (debug_level_d >= Integral::DETAILED) { // print the best instance // printInstance(next_instance_a, level_num_a); } } else { // delete the instance since there is an existing instance // - same history // // print debugging information // if (debug_level_d >= Integral::DETAILED) { // print the best instance // printInstance(next_instance_a, level_num_a); } delete next_instance_a; return false; } curr_score = next_instance_a->getScore(); // update the maximal instance score for the beam pruning // if(getSearchLevel(level_num_a).useBeam() && (curr_score > max_instance_scores_d(level_num_a)) ) { max_instance_scores_d(level_num_a) = curr_score; } // exit gracefully // return true; } // method: ascendInstance // // arguments: // int32 level_num: (input) the level for which we will propagate instances // Instance*& curr_instance_a: (input) the instance that we want to ascend // // return: logical error status // // propagate current instance up in the hierarchy. // only instances at the end of each subgraph are considered // bool8 HierarchicalSearch::ascendInstance(int32 level_num_a, Instance*& curr_instance_a) { // local variable // Instance* new_instance = (Instance*) NULL; Instance* tmp_instance = (Instance*) NULL; Instance* middle_instance = (Instance*) NULL; GraphVertex* tmp_vert = (GraphVertex*)NULL; GraphArc* tmp_arc = (GraphArc*)NULL; float32 tmp_score = 0; bool8 pruning = true; bool8 same_level = false; bool8 dummy_node = false; // must have a history // Context* curr_context = curr_instance_a->getSymbol(); // keep the instance for propagate down // if (curr_context->getLastVertex() == (GraphVertex*)NULL) { // keep the old instance, now exit // return false; } // last vertext is an terminal, ready for propagate up // else if (curr_context->getLastVertex()->isTerm()) { // new instance // //new_instance = curr_instance_a; new_instance = new Instance(*curr_instance_a); new_instance->setFrame((uint32)current_frame_d); // if we are at the top level, generate a NULL right context // if ( level_num_a == 0 ){ //new_instance->setBackPointer(curr_instance_a); new_instance->setSymbol(context_pool_d.setLastAndAllocate(new_instance->getSymbol(), (GraphVertex*)NULL)); // add the instance to current level's instance list // addInstance(level_num_a, curr_instance_a, new_instance, pruning); // old instance was replaced, now exit // return true; } // decrement the history of the new instance // else { // set back pointer // new_instance->setBackPointer(curr_instance_a); // change history, go up one level // changeHistory(new_instance, true); // this part is added for skip-symbols // check with the instance with non-inactive state // if current level is one level above the skip level // the central vertex needs to be swapped // if ( new_instance->getInstanceState() == Instance::PSEUDO_ACTIVE && new_instance->getSkipLevel() == (uint32) level_num_a - 1 ){ // are we generating a symbol graph? // if (getSearchLevel(level_num_a - 1).useSymbolGraph()) { // retrieve the current symbol // Context* symbol = (Context*)NULL; if ((symbol = new_instance->getSymbol()) == (Context*)NULL) { return Error::handle(name(), L"ascendInstance", Error::ARG, __FILE__, __LINE__); } // add the trace to the search node's trace list // int32 index = (int32)nsymbol_indices_d(level_num_a - 1); int32 order = getSearchLevel(level_num_a - 1).getNSymbolOrder(); Instance* existing_instance = (Instance*)NULL; SearchNode* search_node = symbol->getCentralVertex()->getItem(); if (search_node->mergeInstance(new_instance, current_frame_d, existing_instance, index, order)) { SymbolGraphNode* new_symbol_node = (SymbolGraphNode*)NULL; SymbolGraphNode* old_symbol_node = (SymbolGraphNode*)NULL; GraphVertex* nv = (GraphVertex*)NULL; nv = new_instance->getSymbol()->getCentralVertex(); int32 symbol_id = nv->getItem()->getSymbolId(); if (!getSearchLevel(level_num_a - 1).isDummySymbol(symbol_id) && !nv->isStart() && !nv->isTerm()) { SearchSymbol symbol_str; nv->getItem()->getSymbol(symbol_str); // transfer the old symbol graph node // old_symbol_node = curr_instance_a->getSymbolNode(); if (old_symbol_node == (SymbolGraphNode*)NULL) { old_symbol_node = symbol_graph_d.getStart(); old_symbol_node->setFrameIndex((int32)0); old_symbol_node->setParentGraph(&symbol_graph_d); } // when the next instance gets added to the search node // if (existing_instance == (Instance*)NULL) { // when the next instance gets added to the search node // new_symbol_node = symbol_graph_d.insertNode((uint32)current_frame_d, symbol_str); new_instance->setSymbolNode(new_symbol_node); if (debug_level_d >= Integral::DETAILED) { String new_str; new_symbol_node->getSymbol(new_str); String output(L"\n-> creating node: "); output.concat(new_symbol_node); output.concat(L" ["); output.concat(new_str); output.concat(L"], frame: "); output.concat(new_symbol_node->getFrameIndex()); output.concat(L", associated instance: "); output.concat(new_instance); Console::put(output); } } // when the new instance replaces the existing in the search node // else { new_symbol_node = existing_instance->getSymbolNode(); new_instance->setSymbolNode(new_symbol_node); if (debug_level_d >= Integral::DETAILED) { String new_str; new_symbol_node->getSymbol(new_str); String output(L"\n-> transferring node: "); output.concat(new_symbol_node); output.concat(L" ["); output.concat(new_str); output.concat(L"], frame: "); output.concat(new_symbol_node->getFrameIndex()); output.concat(L", from instance: "); output.concat(existing_instance); output.concat(L", to instance: "); output.concat(new_instance); Console::put(output); } } // insert the old symbol graph node into the current nodes history // float32 ac_score = new_instance->getScore(); float32 lm_score = new_instance->getLMScore(); int32 history_paths = getSearchLevel(level_num_a - 1).getHistoryPaths(); new_symbol_node->insertPrevNode(old_symbol_node, ac_score, history_paths, lm_score); } } } Instance* tmp_instance = new Instance(*new_instance); tmp_instance->setFrame((uint32)current_frame_d); //tmp_instance->setBackPointer(new_instance); // set to normal condition // tmp_instance->setInstanceState(Instance::ACTIVE); // swap the central vertex // tmp_vert = (GraphVertex*)tmp_instance->getSkipSymbol(); uint64 symbol_id = (uint64)tmp_instance->getSymbol()->getCentralVertex(); tmp_instance->setSkipSymbol(symbol_id); tmp_instance->setSymbol(context_pool_d.setCentralAndAllocate(tmp_instance->getSymbol(), tmp_vert)); // set the one before central context // tmp_instance->getSymbol()->setBeforeCentralVertex(symbol_id); // print debugging information // if (debug_level_d >= Integral::DETAILED) { // print the best instance // printInstance(new_instance, level_num_a); } // add the instance to current level's instance list // addInstance(level_num_a - 1, new_instance, tmp_instance, pruning); // clean the memory // if (new_instance->getRefCount() < 1 && new_instance != curr_instance_a) { delete new_instance; } // exit gracefully // return true; } if ( new_instance->getInstanceState() == Instance::ACTIVE && new_instance->getSkipLevel() == (uint32) level_num_a - 1 ){ Instance* tmp_instance = new Instance(*new_instance); tmp_instance->setFrame((uint32)current_frame_d); tmp_instance->setBackPointer(new_instance); // set the new pointers // middle_instance = new_instance; new_instance = tmp_instance; // swap the central vertex // tmp_vert = (GraphVertex*)new_instance->getSkipSymbol(); uint64 symbol_id = (uint64)new_instance->getSymbol()->getCentralVertex(); new_instance->setSkipSymbol(symbol_id); new_instance->setSymbol(context_pool_d.setCentralAndAllocate(new_instance->getSymbol(), tmp_vert)); // set to normal condition // new_instance->setInstanceState(Instance::INACTIVE); } tmp_vert = new_instance->getSymbol()->getLastVertex(); } } // central vertext is an terminal, ready for propagate at the same level // else if (curr_context->getLastVertex()->getItem()->isDummyNode()) { // new instance // new_instance = curr_instance_a; tmp_vert = curr_context->getLastVertex(); dummy_node = true; same_level = true; } // central vertext is an terminal, ready for propagate at the same level // else if (curr_context->getCentralVertex()->isStart()) { // new instance // new_instance = curr_instance_a; tmp_vert = curr_context->getLastVertex(); same_level = true; } // last vertext is at one level above, ready for propagate up // else if (curr_context->getLastVertex()->getItem()-> getSearchLevel()->getLevelIndex() == level_num_a - 1) { // new instance // new_instance = new Instance(*curr_instance_a); new_instance->setFrame((uint32)current_frame_d); new_instance->setBackPointer(curr_instance_a); //tmp_score = getPosteriorScore(new_instance); //new_instance->setScore(new_instance->getScore() + tmp_score); // decrement the history of the new instance // changeHistory(new_instance, true); // add the symbol penalty while going to higher level // int32 new_instance_level = curr_context->getLastVertex()->getItem()->getSearchLevel()->getLevelIndex(); float32 symbol_penalty = getSearchLevel(new_instance_level).getSymbolPenalty(); int32 symbol_id = curr_context->getLastVertex()->getItem()->getSymbolId(); // add the symbol insertion penalty if applicable // if (!getSearchLevel(new_instance_level).isDummySymbol(symbol_id) && !getSearchLevel(new_instance_level).isSPenaltyExcludeSymbol(symbol_id) && (curr_context->getLastVertex()->getItem() != (SearchNode*)NULL)) { new_instance->setScore(new_instance->getScore() + symbol_penalty); } new_instance->setSymbol(context_pool_d.shiftAndAllocate(new_instance->getSymbol(), curr_context->getLastVertex())); tmp_vert = new_instance->getSymbol()->getLastVertex(); // apply n-symbol score // applyNSymbolScore(new_instance, level_num_a - 1); } // ready for propagate down, keep this instance // else if ( curr_context->getLastVertex()->getItem()-> getSearchLevel()->getLevelIndex() >= level_num_a ) { // ready for propagate down, keep the instance // return false; } // give error message, it can not happen in a correct situation // else { return Error::handle(name(), L"ascendInstance: Wrong instance", Error::ARG, __FILE__, __LINE__); } // keep the instance for propagate down // if ( tmp_vert == (GraphVertex*)NULL) { // are we generating a symbol graph? // if (!same_level && getSearchLevel(level_num_a - 1).useSymbolGraph()) { // retrieve the current symbol // Context* symbol = (Context*)NULL; if ((symbol = new_instance->getSymbol()) == (Context*)NULL) { return Error::handle(name(), L"ascendInstance", Error::ARG, __FILE__, __LINE__); } // add the trace to the search node's trace list // int32 index = (int32)nsymbol_indices_d(level_num_a - 1); int32 order = getSearchLevel(level_num_a - 1).getNSymbolOrder(); Instance* existing_instance = (Instance*)NULL; SearchNode* search_node = symbol->getCentralVertex()->getItem(); if (search_node->mergeInstance(new_instance, current_frame_d, existing_instance, index, order)) { SymbolGraphNode* new_symbol_node = (SymbolGraphNode*)NULL; SymbolGraphNode* old_symbol_node = (SymbolGraphNode*)NULL; GraphVertex* nv = (GraphVertex*)NULL; nv = new_instance->getSymbol()->getCentralVertex(); int32 symbol_id = nv->getItem()->getSymbolId(); if (!getSearchLevel(level_num_a - 1).isDummySymbol(symbol_id) && !nv->isStart() && !nv->isTerm()) { SearchSymbol symbol_str; nv->getItem()->getSymbol(symbol_str); // transfer the old symbol graph node // old_symbol_node = curr_instance_a->getSymbolNode(); if (old_symbol_node == (SymbolGraphNode*)NULL) { old_symbol_node = symbol_graph_d.getStart(); old_symbol_node->setFrameIndex((int32)0); old_symbol_node->setParentGraph(&symbol_graph_d); } // when the next instance gets added to the search node // if (existing_instance == (Instance*)NULL) { // when the next instance gets added to the search node // new_symbol_node = symbol_graph_d.insertNode((uint32)current_frame_d, symbol_str); new_instance->setSymbolNode(new_symbol_node); if (debug_level_d >= Integral::DETAILED) { String new_str; new_symbol_node->getSymbol(new_str); String output(L"\n-> creating node: "); output.concat(new_symbol_node); output.concat(L" ["); output.concat(new_str); output.concat(L"], frame: "); output.concat(new_symbol_node->getFrameIndex()); output.concat(L", associated instance: "); output.concat(new_instance); Console::put(output); } } // when the new instance replaces the existing in the search node // else { new_symbol_node = existing_instance->getSymbolNode(); new_instance->setSymbolNode(new_symbol_node); if (debug_level_d >= Integral::DETAILED) { String new_str; new_symbol_node->getSymbol(new_str); String output(L"\n-> transferring node: "); output.concat(new_symbol_node); output.concat(L" ["); output.concat(new_str); output.concat(L"], frame: "); output.concat(new_symbol_node->getFrameIndex()); output.concat(L", from instance: "); output.concat(existing_instance); output.concat(L", to instance: "); output.concat(new_instance); Console::put(output); } } // insert the old symbol graph node into the current nodes history // float32 ac_score = new_instance->getScore(); float32 lm_score = new_instance->getLMScore(); int32 history_paths = getSearchLevel(level_num_a - 1).getHistoryPaths(); new_symbol_node->insertPrevNode(old_symbol_node, ac_score, history_paths, lm_score); } } } // new instance // tmp_instance = new Instance(*new_instance); tmp_instance->setFrame((uint32)current_frame_d); // generate a NULL right context // tmp_instance->setSymbol(context_pool_d.shiftAndAllocate(tmp_instance->getSymbol(), (GraphVertex*)NULL)); if ( same_level ){ // print debugging information // if (debug_level_d >= Integral::DETAILED) { // print the best instance // printInstance(new_instance, level_num_a); } // add the instance to current level's instance list // addInstance(level_num_a, new_instance, tmp_instance, pruning); } else { // print debugging information // if (debug_level_d >= Integral::DETAILED) { // print the best instance // printInstance(new_instance, level_num_a); } // add the instance to the higher level's instance list // addInstance(level_num_a - 1 , new_instance, tmp_instance, pruning); } // clean the memory, must clear new_instance first // if (new_instance->getRefCount() < 1 && new_instance != curr_instance_a) { delete new_instance; } // clean the memory, clear the middle_instance the second // if ( middle_instance != NULL ){ if (middle_instance->getRefCount() < 1 && middle_instance != curr_instance_a) { delete middle_instance; } } // exit // return true; } // error, ISIP_REMOVE, this check can be removed // if (tmp_vert->isTerm()) { return Error::handle(name(), L"ascendInstance: Wrong instance", Error::ARG, __FILE__, __LINE__); } // are we generating a symbol graph? // if (!same_level && !tmp_vert->isEmpty() && getSearchLevel(level_num_a - 1).useSymbolGraph()) { // retrieve the current symbol // Context* symbol = (Context*)NULL; if ((symbol = new_instance->getSymbol()) == (Context*)NULL) { return Error::handle(name(), L"ascendInstance", Error::ARG, __FILE__, __LINE__); } // add the trace to the search node's trace list // int32 index = (int32)nsymbol_indices_d(level_num_a - 1); int32 order = getSearchLevel(level_num_a - 1).getNSymbolOrder(); Instance* existing_instance = (Instance*)NULL; SearchNode* search_node = symbol->getCentralVertex()->getItem(); if (search_node->mergeInstance(new_instance, current_frame_d, existing_instance, index, order)) { SymbolGraphNode* new_symbol_node = (SymbolGraphNode*)NULL; SymbolGraphNode* old_symbol_node = (SymbolGraphNode*)NULL; GraphVertex* nv = (GraphVertex*)NULL; nv = new_instance->getSymbol()->getCentralVertex(); int32 symbol_id = nv->getItem()->getSymbolId(); if (!getSearchLevel(level_num_a - 1).isDummySymbol(symbol_id) && !nv->isStart() && !nv->isTerm()) { SearchSymbol symbol_str; nv->getItem()->getSymbol(symbol_str); // transfer the old symbol graph node // old_symbol_node = curr_instance_a->getSymbolNode(); if (old_symbol_node == (SymbolGraphNode*)NULL) { old_symbol_node = symbol_graph_d.getStart(); old_symbol_node->setFrameIndex((int32)0); old_symbol_node->setParentGraph(&symbol_graph_d); } // when the next instance gets added to the search node // if (existing_instance == (Instance*)NULL) { // when the next instance gets added to the search node // new_symbol_node = symbol_graph_d.insertNode((uint32)current_frame_d, symbol_str); new_instance->setSymbolNode(new_symbol_node); if (debug_level_d >= Integral::DETAILED) { String new_str; new_symbol_node->getSymbol(new_str); String output(L"\n-> creating node: "); output.concat(new_symbol_node); output.concat(L" ["); output.concat(new_str); output.concat(L"], frame: "); output.concat(new_symbol_node->getFrameIndex()); output.concat(L", associated instance: "); output.concat(new_instance); Console::put(output); } } // when the new instance replaces the existing in the search node // else { new_symbol_node = existing_instance->getSymbolNode(); new_instance->setSymbolNode(new_symbol_node); if (debug_level_d >= Integral::DETAILED) { String new_str; new_symbol_node->getSymbol(new_str); String output(L"\n-> transferring node: "); output.concat(new_symbol_node); output.concat(L" ["); output.concat(new_str); output.concat(L"], frame: "); output.concat(new_symbol_node->getFrameIndex()); output.concat(L", from instance: "); output.concat(existing_instance); output.concat(L", to instance: "); output.concat(new_instance); Console::put(output); } } // insert the old symbol graph node into the current nodes history // float32 ac_score = new_instance->getScore(); float32 lm_score = new_instance->getLMScore(); int32 history_paths = getSearchLevel(level_num_a - 1).getHistoryPaths(); new_symbol_node->insertPrevNode(old_symbol_node, ac_score, history_paths, lm_score); } } } // generate instances to all next vertices // for (bool8 more_paths = tmp_vert->gotoFirst(); more_paths; more_paths = tmp_vert->gotoNext()) { // create a new instance, we store the extra instance so we // can later view the scores as they are added. this can // be changed later for efficiency // tmp_instance = new Instance(*new_instance); tmp_instance->setFrame((uint32)current_frame_d); // update the score with the arc score // tmp_arc = tmp_vert->getCurr(); tmp_score = tmp_instance->getScore() + tmp_arc->getWeight(); tmp_instance->setScore(tmp_score); // change the history // if ( dummy_node ){ tmp_instance->setSymbol(context_pool_d.setLastAndAllocate(tmp_instance->getSymbol(), tmp_arc->getVertex())); } else{ tmp_instance->setSymbol(context_pool_d.shiftAndAllocate(tmp_instance->getSymbol(), tmp_arc->getVertex())); } // add the instance to current level's instance list // if ( same_level ){ // print debugging information // if (debug_level_d >= Integral::DETAILED) { // print the best instance // printInstance(new_instance, level_num_a); } // set the language model probability // if (getSearchLevel(level_num_a).useRescore()) { tmp_instance->setLMScore(tmp_arc->getLanguageWeight()); } addInstance(level_num_a, new_instance, tmp_instance, pruning); } // add the instance to the higher level's instance list // else { // print debugging information // if (debug_level_d >= Integral::DETAILED) { // print the best instance // printInstance(new_instance, level_num_a); } // set the language model probability // if (getSearchLevel(level_num_a - 1).useRescore()) { tmp_instance->setLMScore(tmp_arc->getLanguageWeight()); } addInstance(level_num_a - 1 , new_instance, tmp_instance, pruning); } } // clean the memory, must clear new_instance first // if (new_instance->getRefCount() < 1 && new_instance != curr_instance_a) { delete new_instance; } // clean the memory, clear the middle_instance the second // if ( middle_instance != NULL ){ if (middle_instance->getRefCount() < 1 && middle_instance != curr_instance_a) { delete middle_instance; } } // exit gracefully // return true; } // method: descendInstance // // arguments: // int32 level_num: (input) the level for which we will propagate instances // Instance*& curr_instance_a: (input) the instance that we want to descend // // return: logical error status // // propagate the instance down the hierarchy. // bool8 HierarchicalSearch::descendInstance(int32 level_num_a, Instance*& curr_instance_a) { // local variable // Context* curr_context = curr_instance_a->getSymbol(); Instance* new_instance = (Instance*) NULL; Instance* tmp_instance = (Instance*) NULL; GraphVertex* tmp_vert = (GraphVertex*)NULL; GraphArc* tmp_arc = (GraphArc*)NULL; float32 tmp_score = 0; bool8 pruning = true; bool8 ascend = false; // if central is NULL, propagate down // if (curr_context->getCentralVertex() == (GraphVertex*)NULL) { // new instances // new_instance = new Instance(*curr_instance_a); new_instance->setFrame((uint32)current_frame_d); // descend one level // changeHistory(new_instance, ascend, level_num_a, (GraphVertex*)NULL); new_instance->setSymbol(context_pool_d.setLastAndAllocate(new_instance->getSymbol(), (GraphVertex*)NULL)); // add the instance to the lower level's instance list // addInstance(level_num_a + 1 , curr_instance_a, new_instance, pruning); // new instance is added, now exit // return true; } // 1) central is start, or // 2) last node is the dummy node, the term node or at a higher level, // ready for propagate up if ((curr_context->getLastVertex() != (GraphVertex*)NULL) && ( curr_context->getCentralVertex()->isStart() || curr_context->getLastVertex()->isTerm() || curr_context->getLastVertex()->getItem()->isDummyNode() || curr_context->getLastVertex()->getItem()-> getSearchLevel()->getLevelIndex() < level_num_a )) { // no new instance generated // return false; } // this part is added for skip-symbols // if curr_instance_a is inactive and the last vertex is "sp" // and level_num_a is the same as the curr_context->getLastVertex() // ->getItem()->getSearchLevel()->getLevelIndex() // 1) find all the successors of sp // 2) generate new instances point to the central vertex, set the status // to pesudo_active, save the vertex "sp" in the instance // 3) return // if ( curr_context->getLastVertex() != (GraphVertex*)NULL) { tmp_vert = curr_context->getLastVertex(); int32 symbol_id = tmp_vert->getItem()->getSymbolId(); // error checking // if ( getSearchLevel(level_num_a).isSkipSymbol(symbol_id) && getSearchLevel(level_num_a).getRightContext() > 1 ){ return Error::handle(name(), L"propagateInstancesDown: skip symbol can't specified at the search level with right context great than one", Error::ARG,__FILE__, __LINE__); } // if current symbol is skip symbol // if ( getSearchLevel(level_num_a).isSkipSymbol(symbol_id) && getSearchLevel(level_num_a).getRightContext() > 0 && tmp_vert->getItem()->getSearchLevel()->getLevelIndex() == level_num_a && curr_context->getCentralVertex()->getItem()->getSearchLevel()->getLevelIndex() == level_num_a ){ // loop over all paths in the subgraph and create new // instances in the next level // for (bool8 more_paths = tmp_vert->gotoFirst(); more_paths; more_paths = tmp_vert->gotoNext()) { // initialize central vertex of the context // tmp_arc = tmp_vert->getCurr(); // create a new instance, we store the extra instance so we // can later view the scores as they are added. this can // be changed later for efficiency // tmp_instance = new Instance(*curr_instance_a); tmp_instance->setFrame((uint32)current_frame_d); // update the score with the arc score // tmp_score = tmp_instance->getScore() + tmp_arc->getWeight(); tmp_instance->setScore(tmp_score); // set the instance as special // tmp_instance->setSkipSymbol((uint64)tmp_vert); tmp_instance->setSkipLevel(level_num_a); tmp_instance->setInstanceState(Instance::PSEUDO_ACTIVE); tmp_instance->setSymbol(context_pool_d.setLastAndAllocate(tmp_instance->getSymbol(), tmp_arc->getVertex())); // set the language model probability // if (getSearchLevel(level_num_a).useRescore()) { tmp_instance->setLMScore(tmp_arc->getLanguageWeight()); } // add the instance to current level's instance list // addInstance(level_num_a, curr_instance_a, tmp_instance, false); } // exit gracefully // return true; } } // central vertext is at the same level , ready for propagate down // if (curr_context->getCentralVertex()->getItem()-> getSearchLevel()->getLevelIndex() == level_num_a ) { // new instance // new_instance = curr_instance_a; new_instance->setFrame((uint32)current_frame_d); // acces the subgraph's start vertex // SearchLevel& sl_curr = getSearchLevel(level_num_a); SearchLevel& sl_lower = getSearchLevel(level_num_a + 1); // convert context vertices to search symbol indices // we need to do it before hashing in getSubGraphIndex // Context convert_context = *curr_context; Context* tmp_context = (Context*)NULL; Ulong* subgr_ind = (Ulong*)NULL; int32 symbol_id = curr_context->getCentralVertex()-> getItem()->getSymbolId(); // this part is added for skip-symbols // if curr_instance is active and the central is sp, evaluate // sp and replace the central sp with the original vertex, set to // if ( getSearchLevel(level_num_a).isSkipSymbol(symbol_id) ){ // if the instance is not active, return error // if ( new_instance->getInstanceState() != Instance::ACTIVE ){ return Error::handle(name(), L"propagateInstancesDown: search error, incorrect state for skip symbol", Error::ARG,__FILE__, __LINE__); } else{ // swap the central vertex // //tmp_vert = (GraphVertex*)new_instance->getSkipSymbol(); //new_instance->getHistory()->peek()->setCentralVertex((uint32)tmp_vert); // back to normal operation // //new_instance->setInstanceState(Instance::INACTIVE); } } // special case for those context-less symbols // if ( getSearchLevel(level_num_a).isContextLessSymbol(symbol_id) || getSearchLevel(level_num_a).isSkipSymbol(symbol_id) ){ // generate the new context // int32 left_context_length = getSearchLevel(level_num_a).getLeftContext(); int32 right_context_length = getSearchLevel(level_num_a).getRightContext(); int32 central_pos = right_context_length + 1; int32 total_context_length = left_context_length + central_pos; // error checking // if (getSearchLevel(level_num_a).getLeftContext() != getSearchLevel(level_num_a).getRightContext()) { return Error::handle(name(), L"descendInstance - left and right context lengths must be the same", Error::ARG, __FILE__, __LINE__); } // initialize the left context // tmp_context = new Context(total_context_length, central_pos); for (int32 i = 0; i < left_context_length; i++) { tmp_context->assignAndAdvance(getSearchLevel(level_num_a).getSymbolIndex(SearchSymbol::NO_LEFT_CONTEXT)); } // initialize central vertex of the context // tmp_context->assignAndAdvance(symbol_id); // initialize right vertices of the context // for (int32 i = 0; i < right_context_length; i++) { tmp_context->assignAndAdvance(getSearchLevel(level_num_a).getSymbolIndex(SearchSymbol::NO_RIGHT_CONTEXT)); } } // if it is not the context less symbol // else{ convert_context.convert(tmp_context); } // get the index corresponding to the current context // subgr_ind = sl_curr.getSubGraphIndex(*tmp_context); if (subgr_ind == (Ulong*)NULL) { String context; curr_context->print(context); String output(L"**** no subgraph found for context "); output.concat(context); output.concat(L" at level "); output.concat(level_num_a); output.concat(L" ****"); Console::put(output); return Error::handle(name(), L"propagateInstancesDown", Error::ARG, __FILE__, __LINE__); } if (tmp_context != (Context*)NULL) { delete tmp_context; } // get the subgraph start vertex // tmp_vert = (sl_lower.getSubGraph((int32)*subgr_ind)).getStart(); // loop over all paths in the subgraph and create new // instances in the next level // for (bool8 more_paths = tmp_vert->gotoFirst(); more_paths; more_paths = tmp_vert->gotoNext()) { // initialize central vertex of the context // tmp_arc = tmp_vert->getCurr(); // create a new instance, we store the extra instance so we // can later view the scores as they are added. this can // be changed later for efficiency // tmp_instance = new Instance(*new_instance); tmp_instance->setFrame((uint32)current_frame_d); // update the score with the arc score // tmp_score = tmp_instance->getScore() + tmp_arc->getWeight(); tmp_instance->setScore(tmp_score); // change the history // changeHistory(tmp_instance, ascend, level_num_a, tmp_vert); tmp_instance->setSymbol(context_pool_d.setLastAndAllocate(tmp_instance->getSymbol(), tmp_arc->getVertex())); // print debugging information // if (debug_level_d >= Integral::DETAILED) { // print the best instance // printInstance(new_instance, level_num_a); } // set the language model probability // if (getSearchLevel(level_num_a + 1).useRescore()) { tmp_instance->setLMScore(tmp_arc->getLanguageWeight()); } // add the instance to current level's instance list // addInstance(level_num_a + 1 , new_instance, tmp_instance, pruning); } // clean the memory // if (new_instance->getRefCount() < 1 && new_instance != curr_instance_a) { delete new_instance; } // new instance generated // return true; } // central vertext is at a lower level , ready for propagate down // set the nxt level context as start-start+curr_central_context // the start will be treated in the propagte up stage // else if (curr_context->getCentralVertex()->getItem()-> getSearchLevel()->getLevelIndex() > level_num_a ) { // get the central vertex // tmp_vert = curr_context->getCentralVertex(); // new instance // new_instance = new Instance(*curr_instance_a); new_instance->setFrame((uint32)current_frame_d); // currently , different level has different left context node // we must set it to the correct level // tmp_vert = tmp_vert->getItem()->getSearchLevel()-> getSubGraph((int32)0).getStart(); // change the history // changeHistory(new_instance, ascend, level_num_a, tmp_vert); new_instance->setSymbol(context_pool_d.setLastAndAllocate(new_instance->getSymbol(), curr_context->getCentralVertex())); // set the language model probability // if (getSearchLevel(level_num_a + 1).useRescore()) { new_instance->setLMScore(tmp_arc->getLanguageWeight()); } // add the instance to current level's instance list // addInstance(level_num_a + 1 , curr_instance_a, new_instance, pruning); // new instance generated // return true; } // error, can not happen // else { return Error::handle(name(), L"ascendInstance: Wrong instance", Error::ARG, __FILE__, __LINE__); } // exit gracefully // return true; } // method: propagateLexInstancesUp // // arguments: // int32 level_num: (input) the level for which we will propagate instances // // return: logical error status // // propagate all instances up the hierarchy. only instances at the end of a // each subgraph are considered // bool8 HierarchicalSearch::propagateLexInstancesUp(int32 level_num_a) { // algorithm for this method: propagateLexInstancesUp // define local variables // bool8 status = false; bool8 end_loop = false; Instance* curr_instance = (Instance*)NULL; Context useless; // make sure there is at least one instance to propagate // if (instance_lists_d(level_num_a).length() < 1) { return false; } // loop over all current instances and create the next level's instances. // all new instances will go at the end of the list so we set the mark to // tell us when to stop propagating // instance_lists_d(level_num_a).gotoLast(); instance_lists_d(level_num_a).setMark(); instance_lists_d(level_num_a).gotoFirst(); while (!end_loop) { // loop until we reached the marked element // end_loop = instance_lists_d(level_num_a).isMarkedElement(); // get the current first instance from the list // instance_lists_d(level_num_a).removeFirst(curr_instance); // if the instance is inactive then delete it and its backpath if necessary // if (!curr_instance->isActive()) { if (search_mode_d == DECODE) { Instance::deleteInstance(curr_instance, true); } } // else, extend paths and update scores // else { // if we propagate new instances, but not sure they are pruned or not // if ( ascendInstance(level_num_a, curr_instance) ) { // if all new instances are pruned // bump the current instance off of the instance list // if (curr_instance->getRefCount() < 1) { // delete the instance // if (search_mode_d == DECODE) { Instance::deleteInstance(curr_instance, true); } } else { // now, there is at least one new instance survived // status = true; } instance_lists_d(level_num_a).gotoFirst(); } // when the instance is NOT at the end of the current subgraph we keep // it at this level for now it gets propagated forwards during the // evaluateLexInstanceModels function // else { float32 curr_score = curr_instance->getScore(); // update the maximal instance score for the beam pruning // if(getSearchLevel(level_num_a).useBeam() && (curr_score > max_instance_scores_d(level_num_a)) ) { max_instance_scores_d(level_num_a) = curr_score; } // keep the instance on this level // instance_lists_d(level_num_a).insertLast(curr_instance); instance_lists_d(level_num_a).gotoFirst(); } } } // exit gracefully // return status; } // method: propagateLexInstancesDown // // arguments: // int32 level_num: (input) the level for which we will propagate LexInstances // // return: logical error status // // propagate all instances down the hierarchy. // bool8 HierarchicalSearch::propagateLexInstancesDown(int32 level_num_a) { // algorithm for this method: // define local variables // Instance* curr_instance = (Instance*)NULL; bool8 status = false; bool8 end_loop = false; // make sure there is at least one instance to propagate // if (instance_lists_d(level_num_a).length() < 1) { return false; } // switch on whether we are at the lowest level or not // // if we are not at the lowest level, push instances down the hierarchy - // there should be no instances left at this level when we are done // instance_lists_d(level_num_a).gotoLast(); instance_lists_d(level_num_a).setMark(); instance_lists_d(level_num_a).gotoFirst(); if (level_num_a != getNumLevels() - 1) { // loop over all current instances and create the next level's instances // while (!end_loop) { // loop until we reached the marked element // end_loop = instance_lists_d(level_num_a).isMarkedElement(); // get the current vertex in the search graph // instance_lists_d(level_num_a).removeFirst(curr_instance); // delete this instance if it is now inactive // if (!curr_instance->isActive()) { // bump the current instance off of the instance list and delete it // and its backpath if necessary // if (search_mode_d == DECODE) { Instance::deleteInstance(curr_instance, true); } } // if it is active then propagate it // else { // if central is NULL, propagate down // if (curr_instance->getSymbol()->getCentralVertex() == (GraphVertex*)NULL) { if ( (level_num_a + 1) == (getNumLevels() - 1) ){ instance_valid_hyps_d.insertLast(curr_instance); // go for next instance // continue; } } // if we propagate new instances, but not sure they are pruned or not // if ( descendInstance(level_num_a, curr_instance) ) { // if all new instances are pruned // bump the current instance off of the instance list // if (curr_instance->getRefCount() < 1) { if (search_mode_d == DECODE) { Instance::deleteInstance(curr_instance, true); } } else { // now, there is new instance survived // status = true; } instance_lists_d(level_num_a).gotoFirst(); } // else if no new instances can be generated. // else { float32 curr_score = curr_instance->getScore(); // update the maximal instance score for the beam pruning // if(getSearchLevel(level_num_a).useBeam() && (curr_score > max_instance_scores_d(level_num_a)) ) { max_instance_scores_d(level_num_a) = curr_score; } // keep the instance on this level // instance_lists_d(level_num_a).insertLast(curr_instance); instance_lists_d(level_num_a).gotoFirst(); } } } } // exit gracefully // return status; } // method: networkDecoder // // arguments: // Vector& fe: (input) vector of inputs // int32 num_frames: (input) the number of steps to move forward // // return: logical error status // // decode part (or all) of the search space // bool8 HierarchicalSearch::networkDecoder(Vector& fe_a, int32 num_frames_a) { // if we haven't started the search then we need to initialize the // search // if ((int32)current_frame_d == DEF_START_FRAME) { initializeNetworkDecoder(); } // determine the number of frames to loop through. If the user specifies // to loop over all frames then the frame_num is set to a default value // so that the decoder loops indefinitely // int32 frame_num = 0; if (num_frames_a == DEF_NUM_FRAMES) { frame_num = num_frames_a - 1; } // loop over the specified number of frames // int32 size = fe_a.length(); while (current_frame_d < size && features_d.assign(fe_a(current_frame_d)) && frame_num < num_frames_a) { // decode one frame of data // if (!traverseLexInstanceLevels()) { break; } // increment the frame_num if necessary - otherwise we loop indefinitely // if (num_frames_a != DEF_NUM_FRAMES) { frame_num++; } } // exit gracefully // return true; } // method: networkDecoder // // arguments: // Vector& vector_fe: (input) front-ends for extracting features // int32 num_frames_a: (input) the number of steps to move forward // // return: logical error status // // decode part (or all) of the search space // bool8 HierarchicalSearch::networkDecoder(Vector& vector_fe_a, int32 num_frames_a) { // if we haven't started the search then we need to initialize the // search // if ((int32)current_frame_d == DEF_START_FRAME) { initializeNetworkDecoder(); } // determine the number of frames to loop through. If the user specifies // to loop over all frames then the frame_num is set to a default value // so that the decoder loops indefinitely // int32 frame_num = 0; if (num_frames_a == DEF_NUM_FRAMES) { frame_num = num_frames_a - 1; } // loop over all the front ends except the last one that generates // the feature data // for (int32 i = 0; i < vector_fe_a.length() - 1; i++) { vector_fe_a(i).getVector(features_d, 0, current_frame_d); } // loop over the specified number of frames // ISIP_BUG: (hamaker) the channel is set to zero here which won't be // right for multi-channel data // while (vector_fe_a(vector_fe_a.length() - 1).getVector(features_d, 0, current_frame_d) && frame_num < num_frames_a) { // ISIP_BUG: check the feature length here // decode one frame of data // if (!traverseLexInstanceLevels()) { break; } // increment the frame_num if necessary - otherwise we loop indefinitely // if (num_frames_a != DEF_NUM_FRAMES) { frame_num++; } } // exit gracefully // return true; } // method: initializeNetworkDecoder // // arguments: none // // return: logical error status // // initialize the lists, etc. needed to begin searching // bool8 HierarchicalSearch::initializeNetworkDecoder() { // loccal variable // int32 num_levels = getNumLevels(); // make sure that we have at least one level defined // if ( num_levels < 1) { return Error::handle(name(), L"initializeLexNetworkDecoder", HierarchicalSearch::ERR_LEVEL, __FILE__, __LINE__); } // set the current frame // current_frame_d = 0; // clear the valid_hyps_d list // clearInstanceStorage(); // clear the instance lists of all the search nodes // clearSearchNodesInstanceLists(); // clear the trellis before starting // if (search_mode_d == TRAIN) { return Error::handle(name(), L"initializeLexNetworkDecoder: can't used in training mode", HierarchicalSearch::ERR_LEVEL, __FILE__, __LINE__); } // initialize lexical trees // for (int32 i = 0; i < num_levels ; i++){ if ( getSearchLevel(i).useLexicalTree()){ expandLexicalTree(i); } } // generate initial instances for the search engine // networkLexStart(); // exit gracefully // return true; } // method: networkLexStart // // arguments: // // return: logical error status // // start search engin with a network structure // bool8 HierarchicalSearch::networkLexStart(){ // seed the top instance list with the start node of the search graph // Instance* tmp_instance = new Instance(); if (search_mode_d == TRAIN) { tmp_instance ->setInstanceMode(Instance::TRAIN); } tmp_instance ->setFrame((uint32)current_frame_d); // has the history been previously generated? if so reuse the history, // if not generate a new history and add it to the history pool // tmp_instance->setHistory(history_pool_d.initAndAllocate()); tmp_instance->setSymbolStack(history_pool_d.initAndAllocate()); // set the start vertex // GraphVertex* tmp_vert = (*h_digraph_d)((int32)initial_level_d).getSubGraph(0).getStart(); // descend this original instance to level 0, that why we set // the level number to -1: (-1 + 1 = 0) // changeHistory(tmp_instance, false, -1, tmp_vert); // add the instance to the instance list // Instance* start_instance = (Instance*)NULL; // initialize the structure that holds the n-symbols // initializeNsymbolInstance(tmp_instance); // add to the instance list // addInstance(0, start_instance, tmp_instance, false); // exit gracefully // return true; } // method: traverseLexInstanceLevels // // arguments: none // // return: logical error status // // do a single-step traversal of the hypotheses at each level // bool8 HierarchicalSearch::traverseLexInstanceLevels() { // define local variables // bool8 status = false; // make sure we have some paths left to traverse // if (!pathsRemainInstance()) { return false; } // propagate instances forward until they are all ready to be evaluated // status = (propagateLexInstances() || status); // now we evaluate all instances that are in the lowest level and move // them forward one arc. viterbi pruning takes place at this level // as does beam pruning. // // lexical tree can't be at this level // status = (evaluateLexInstanceModels() || status); // exit gracefully // return status; } // method: propagateLexInstances // // arguments: none // // return: logical error status // // move instances through the hierarchy until all active instances are ready to be // evaluated // bool8 HierarchicalSearch::propagateLexInstances() { // define local variables // int32 level_num = 0; bool8 status = true; int32 num_levels = getNumLevels(); String out; // clear the hypothesis list since we are generating new hypotheses for this // frame // clearValidHypsLexInstance(); // move all instances forward in the search space. we do this by // pushing instances up and down in the hierarchy until they all rest // in a state that is ready to be evaluated. if there is an infinite // "skip" loop in the search graph then this process will go into an // infinite loop. an infinite skip loop is of the form: // A -> B && B -> A. // this infinite loop structure may be masked by the fact that it // extends over multiple search levels. // // when we exit the while loop below, all instances should be in the lowest // level and should be ready for evaluation. // while ((getActiveInstances() != getActiveInstances(num_levels - 1)) || status) { // status indicates whether any movement in the instances happened // status = false; for (level_num = 0; level_num < num_levels; level_num++) { if (getSearchLevel(level_num).useBeam()) { max_instance_scores_d(level_num) = Instance::INACTIVE_SCORE; } } // work from the bottom up until we reach a point where all instances // are ready to descend again. this segment takes care of // posterior scores such as nsymbol probabilities and applies // pruning (beam and instance) at each level. // for (level_num = num_levels - 1; level_num >= 0; level_num--) { if (debug_level_d >= Integral::DETAILED) { String output; output.assign(L"propagating instances up from level: "); output.concat(level_num); output.concat(L" in frame: "); output.concat(current_frame_d); Console::put(output); } // propagate up // status = (propagateLexInstancesUp(level_num) || status); } // propagate instances down the hierarchy, carrying out viterbi pruning // as we go. // for (level_num = (int32)initial_level_d; level_num < num_levels - 1; level_num++) { // beam pruning // if (getSearchLevel(level_num).useBeam()) { if (debug_level_d >= Integral::DETAILED) { Console::put(L"\nbeam pruning after propagation instances up"); } beamPruneLexInstance(level_num); } // instance pruning // if (getSearchLevel(level_num).useInstance()) { if (debug_level_d >= Integral::DETAILED) { Console::put(L"\ninstance pruning after propagation instances up"); } instancePruneLexInstance(level_num); } // print debug infomation // if (debug_level_d >= Integral::DETAILED) { String output; output.assign(L"propagating instances down from level: "); output.concat(level_num); output.concat(L" in frame: "); output.concat(current_frame_d); Console::put(output); } // propagate down // status = (propagateLexInstancesDown(level_num) || status); } } // print debugging information // if (debug_level_d >= Integral::ALL) { String val; val.assign(L"Frame:"); val.concat(current_frame_d); val.concat(L" Instances left:"); val.concat(getActiveInstances(num_levels - 1)); Console::put(val); } // exit gracefully // return true; } // method: expandLexicalTree // // arguments: // // return: logical error status // // expand graphs into lexical trees // bool8 HierarchicalSearch::expandLexicalTree(int32 level_num_a) { // check with the lexical tree level // if ( level_num_a > ( getNumLevels() - 1) || level_num_a < 0 ) { return Error::handle(name(), L"expandLexicalTree: wrong lexical tree level", HierarchicalSearch::ERR_LEVEL, __FILE__, __LINE__); } // build the lexical tree from top to down // for (int32 i = 0; i < (*h_digraph_d)(level_num_a).getSubGraphs().length(); i++ ){ DiGraph& word_graph = (*h_digraph_d)(level_num_a).getSubGraph((int32)i); //h_digraph_d(level_num_a+1).debug(L"h_digraph_d"); //h_digraph_d(level_num_a+1).getSubGraphs().debug(L"sub_graphs_d"); // expand the top level graph to a lexical tree // LexicalTree::expandLexicalTree(word_graph, (*h_digraph_d)(level_num_a+1).getSubGraphs(), level_num_a); } // exit gracefully // return true; } // method: getLexHypotheses // // arguments: // String& output_hyp: (output) the current search hypotheses // int32 level: (input) the level to print hypotheses from // float32& total_score: (output) the hypothesis total score // int32& num_frames: (output) frame index of the last instance // DoubleLinkedList& instance_path: (output) best hypothesis instance path // // return: logical error status // // build a graph representing the hypotheses and return it // bool8 HierarchicalSearch::getLexHypotheses(String& output_hyp_a, int32 level_a, float32& total_score_a, int32& num_frames_a, DoubleLinkedList& instance_path_a) { // declare local variables // Instance* tmp_instance = (Instance*)NULL; SearchNode* prev_node = (SearchNode*)NULL; SearchNode* tmp_node = (SearchNode*)NULL; int32 counter = 0; int32 curr_level = 0; int32 frame_ind = 0; int32 prev_frame_ind = -1; int32 back_count = 0; float32 score = 0.0; float32 prev_score = 0.0; int32 symbol_id = 0; String out_str; SearchSymbol sym; // clear the output and set the allocation mode for the instance path // output_hyp_a.clear(); instance_path_a.clear(); instance_path_a.setAllocationMode(DstrBase::USER); // move all instances forward in the search space // if (!propagateLexInstances()) { return false; } // make sure we have at least one valid hypothesis // if (instance_valid_hyps_d.length() < 1) { return false; } // loop over all valid instances in the hypothesis list // instance_valid_hyps_d.gotoFirst(); Instance* best_end_hyp = instance_valid_hyps_d.getCurr(); // find the instance with the best score, i.e., best hypothesis instance // while (true) { if (!instance_valid_hyps_d.gotoNext()) { break; } tmp_instance = instance_valid_hyps_d.getCurr(); if (tmp_instance->getScore() > best_end_hyp->getScore()) { best_end_hyp = tmp_instance; } } // print debugging information // if (debug_level_d >= Integral::DETAILED) { // print the best instance // printInstance(best_end_hyp, -1, true); } // backtrack from the best hypothesis instance and generate the instance path // for (tmp_instance = best_end_hyp; tmp_instance != (Instance*)NULL; tmp_instance = tmp_instance->getBackPointer()) { instance_path_a.insertFirst(tmp_instance); back_count++; } // use the best hypothesis instance path to generate the hypothesis string // for (bool8 more_instances = instance_path_a.gotoFirst(); more_instances; more_instances = instance_path_a.gotoNext()) { counter++; tmp_instance = instance_path_a.getCurr(); frame_ind = tmp_instance->getFrame(); // get the central vertex from the top of the history stack // GraphVertex* tmp_vertex = (GraphVertex*)NULL; tmp_vertex = tmp_instance->getSymbol()->getCentralVertex(); // check for a NULL vertex // if (tmp_vertex == (GraphVertex*)NULL) { prev_score = tmp_instance->getScore(); score = prev_score; } // make sure the vertex is neither the dummy // start nor terminating node // else if ((!tmp_vertex->isStart()) && (!tmp_vertex->isTerm())) { tmp_node = tmp_vertex->getItem(); curr_level = tmp_node->getSearchLevel()->getLevelIndex(); if ((level_a < 0) && (curr_level == 0)) { tmp_node->getSymbol(sym); score = tmp_instance->getScore(); symbol_id = tmp_node->getSymbolId(); // generate the output hypothesis containing only search symbols // if (!getSearchLevel(curr_level).isExcludeSymbol(symbol_id)) { out_str.assign(sym); out_str.concat(L" "); } else { out_str.assign(L""); } // append partial string to the complete hypothesis report // if ( frame_ind != prev_frame_ind ) { output_hyp_a.concat(out_str); } prev_node = tmp_node; prev_score = score; prev_frame_ind = frame_ind; } if ((level_a >= 0) && (curr_level == level_a)) { String context; tmp_instance->getSymbol()->print(context); score = tmp_instance->getScore(); sym.assign(context); // generate the output hypothesis // if (counter > 1) { out_str.assign(L"\n"); } else { out_str.assign(L""); } // append previous frame index // if (level_a != (getNumLevels() - 1)) { out_str.concat(prev_frame_ind); } else { out_str.concat(prev_frame_ind + 1); } out_str.concat(L"\t"); // append current frame index // if (level_a != (getNumLevels() - 1)) { out_str.concat(frame_ind); } else { out_str.concat(frame_ind + 1); } out_str.concat(L"\t"); // append search symbol // out_str.concat(sym); out_str.concat(L"\t\t"); // append score // out_str.concat(score - prev_score); // append partial string to the complete hypothesis report // if (level_a == (getNumLevels() - 1)) { output_hyp_a.concat(out_str); } else { if ( frame_ind != prev_frame_ind ) { output_hyp_a.concat(out_str); } } prev_node = tmp_node; prev_score = score; prev_frame_ind = frame_ind; } } } total_score_a = score; num_frames_a = frame_ind; // exit gracefully // return true; } // method: evaluateLexInstanceModels // // arguments: (none) // // return: logical error status. // // evaluate all statistical models // bool8 HierarchicalSearch::evaluateLexInstanceModels() { // define local variables // String out; String val; int32 level_num = getNumLevels() - 1; bool8 end_loop = false; Instance* curr_instance = (Instance*)NULL; Instance* next_instance = (Instance*)NULL; GraphVertex* curr_vert = (GraphVertex*)NULL; SearchSymbol item; // output the frame information // if (debug_level_d >= Integral::DETAILED) { out.assign(L"\n-> evaluating data in frame: "); val.assign((uint64)current_frame_d); out.concat(val); Console::put(out); } // if the beam pruning is required at this level // initialize the maximal instance score // if(getSearchLevel(level_num).useBeam()) { max_instance_scores_d(level_num) = Instance::INACTIVE_SCORE; } // loop over all active instances and score them // for (bool8 more_instances = instance_lists_d(level_num).gotoFirst(); more_instances; more_instances = instance_lists_d(level_num).gotoNext()) { // get the current vertex in the search graph // curr_instance = instance_lists_d(level_num).getCurr(); curr_vert = curr_instance->getSymbol()->getCentralVertex(); // evaluate the statistical model // float32 new_score = curr_instance->getScore() + curr_vert->getItem()->evaluateData(features_d, (int32)current_frame_d); curr_instance->setScore(new_score); // update the maximal instance score for the beam pruning // if(getSearchLevel(level_num).useBeam() && (new_score > max_instance_scores_d(level_num))) { max_instance_scores_d(level_num) = new_score; } } // beam pruning at this level // if (getSearchLevel(getNumLevels() - 1).useBeam()) { if (debug_level_d >= Integral::DETAILED) { Console::put(L"\nbeam pruning after propagation instances up"); } beamPruneLexInstance(getNumLevels() - 1); } // instance pruning at this level // if (getSearchLevel(getNumLevels() - 1).useInstance()) { if (debug_level_d >= Integral::ALL) { Console::put(L"\ninstance npruning after propagation instances up"); } instancePruneLexInstance(getNumLevels() - 1); } // update current frame // - instances generated later will correspond to the next frame // current_frame_d += 1 ; // print debugging information // if (debug_level_d >= Integral::DETAILED) { out.assign(L"\n-> time changed to: "); out.concat(current_frame_d); Console::put(out); } // we mark the current end of the list so we only propagate those instances // forward that were just evaluated // instance_lists_d(level_num).gotoLast(); instance_lists_d(level_num).setMark(); instance_lists_d(level_num).gotoFirst(); // print debugging information // if (debug_level_d >= Integral::DETAILED) { Console::put(L"\npropagating instances forward after the model evaluation"); } // loop until we have propagated all evaluated instances forward // end_loop = instance_lists_d(level_num).isEmpty(); while (!end_loop) { end_loop = instance_lists_d(level_num).isMarkedElement(); // get the current vertex in the search graph // curr_instance = instance_lists_d(level_num).getCurr(); curr_vert = curr_instance->getSymbol()->getLastVertex(); // if this instance is inactive, then delete it // if (!curr_instance->isActive()) { // bump the current instance off of the instance list // if (debug_level_d >= Integral::ALL) { Console::put(L" not active"); } instance_lists_d(level_num).removeFirst(curr_instance); Instance::deleteInstance(curr_instance, true); } // else, extend paths and apply viterbi pruning // else { // extend all paths from that vertex and apply viterbi pruning // for (bool8 more_paths = curr_vert->gotoFirst(); more_paths; more_paths = curr_vert->gotoNext()) { // create a new instance // next_instance = new Instance(*curr_instance); next_instance->setFrame((uint32)current_frame_d); // determine the symbol insertion penalty and transition scale factor // float32 tr_scale = getSearchLevel(level_num).getTrScale(); // update the score with the arc score // GraphArc* tmp_arc = curr_vert->getCurr(); float32 transition_score = tr_scale * tmp_arc->getWeight(); next_instance->setScore(next_instance->getScore() + transition_score); // update the history with the next node at this level // next_instance->setSymbol(context_pool_d.shiftAndAllocate(next_instance->getSymbol(), tmp_arc->getVertex())); // set the backpointer // next_instance->setBackPointer(curr_instance); // apply n-symbol score // applyNSymbolScore(next_instance, level_num); // set the language model probability // if (getSearchLevel(level_num).useRescore()) { next_instance->setLMScore(tmp_arc->getLanguageWeight()); } // add the instance to the search node's instance list // Instance* existing_instance = (Instance*)NULL; SearchNode* next_node = next_instance->getSymbol()-> getCentralVertex()->getItem(); if (next_node->addInstance(next_instance, current_frame_d, existing_instance)) { // add the instance to this level's instance list // instance_lists_d(level_num).insertLast(next_instance); // print debugging information // if (debug_level_d >= Integral::DETAILED) { // print the best instance // printInstance(next_instance, level_num); } // insert the trace in the trellis // if (search_mode_d == TRAIN) { if (!insertNewPath(curr_instance, next_instance, tmp_arc->getWeight())) { return Error::handle(name(), L"evaluateModels", Error::ARG, __FILE__, __LINE__); } } } else { // delete the instance since there is an existing instance // - same history // // print debugging information // if (debug_level_d >= Integral::DETAILED) { // print the best instance // printInstance(next_instance, level_num); } delete next_instance; if (search_mode_d == TRAIN) { if (existing_instance != (Instance*)NULL) { if (!insertOldPath(curr_instance, existing_instance, tmp_arc->getWeight())) { return Error::handle(name(), L"evaluateModels", Error::ARG, __FILE__, __LINE__); } } else { return Error::handle(name(), L"existing instance", Error::ARG, __FILE__, __LINE__); } } } } // bump the current instance off of the instance list // instance_lists_d(level_num).removeFirst(curr_instance); if (curr_instance->getRefCount() < 1) { Instance::deleteInstance(curr_instance, true); } instance_lists_d(level_num).gotoFirst(); } // end if the instance is active } // end while (!end_loop) // exit gracefully // return true; } // method: instancePruneLexInstance // // arguments: // int32 level_num: (input) the level for which we will propagate traces // // return: logical error status. // bool8 HierarchicalSearch::instancePruneLexInstance(int32 level_num_a) { // define local variables // Instance* curr_instance = (Instance*)NULL; int32 threshold = (*h_digraph_d)(level_num_a).getInstanceThreshold(); int32 pruned_instances = 0; int32 orig_length = instance_lists_d(level_num_a).length(); // check if we need to prune any instances at this level // if (orig_length > threshold) { int32 num_to_remove = orig_length - threshold; // sort the instances // instance_lists_d(level_num_a).sort(Integral::ASCENDING, DstrBase::RAND_QUICK); // loop over all active instances at this level // for (int32 i=0; i < num_to_remove; i++) { instance_lists_d(level_num_a).remove(curr_instance); if (curr_instance->getRefCount() < 1) { Instance::deleteInstance(curr_instance, true); } pruned_instances++; } } if (debug_level_d >= Integral::DETAILED) { String output(L"frame: "); output.concat(current_frame_d); output.concat(L", level: "); output.concat(level_num_a); output.concat(L", original instances: "); output.concat(orig_length); output.concat(L", pruned instances: "); output.concat(pruned_instances); output.concat(L", current instances: "); output.concat(instance_lists_d(level_num_a).length()); output.concat(L", threshold: "); output.concat(threshold); output.concat(L"\n"); Console::put(output); } // exit gracefully // return true; } // method: beamPruneLexInstance // // arguments: // int32 level_num: (input) the level for which we will propagate traces // // return: logical error status. // bool8 HierarchicalSearch::beamPruneLexInstance(int32 level_num_a) { // define local variables // Instance* curr_instance = (Instance*)NULL; float32 threshold = max_instance_scores_d(level_num_a) - (*h_digraph_d)(level_num_a).getBeamThreshold(); float32 curr_score; int32 pruned_instances = 0; int32 orig_length = instance_lists_d(level_num_a).length(); // loop over all active instances at this level // bool8 more_instances = instance_lists_d(level_num_a).gotoFirst(); while (more_instances) { curr_instance = instance_lists_d(level_num_a).getCurr(); curr_score = curr_instance->getScore(); if (curr_score > max_instance_scores_d(level_num_a)) { return Error::handle(name(), L"beamPruneLexInstance - bad maximal score", Error::ARG, __FILE__, __LINE__); } // prune the instances with too low score // if (curr_score < threshold) { if (debug_level_d >= Integral::ALL) { String output(L"score is smaller than threshold: "); output.concat(curr_score); output.concat(L", instance:" ); output.concat(curr_instance); Console::put(output); } if (instance_lists_d(level_num_a).isLast()) { more_instances = false; } // bump the current instance off of the instance list // instance_lists_d(level_num_a).remove(); if (curr_instance->getRefCount() < 1) { Instance::deleteInstance(curr_instance, true); } pruned_instances++; } else { if (debug_level_d >= Integral::ALL) { String output(L"score is not smaller than threshold: "); output.concat(curr_score); output.concat(L", instance:" ); output.concat(curr_instance); Console::put(output); } more_instances = instance_lists_d(level_num_a).gotoNext(); } } if (debug_level_d >= Integral::DETAILED) { String output(L"frame: "); output.concat(current_frame_d); output.concat(L", level: "); output.concat(level_num_a); output.concat(L", original instances: "); output.concat(orig_length); output.concat(L", pruned instances: "); output.concat(pruned_instances); output.concat(L", current instances: "); output.concat(instance_lists_d(level_num_a).length()); output.concat(L", threshold: "); output.concat(threshold); output.concat(L", max instance score: "); output.concat(max_instance_scores_d(level_num_a)); output.concat(L"\n"); Console::put(output); } // exit gracefully // return true; } // method: clearValidHypsLexInstance // // arguments: none // // return: logical error status // // clear the instances stored in the valid hypothesis list // bool8 HierarchicalSearch::clearValidHypsLexInstance() { // define local variables // Instance* tmp_instance; // use the trace_instance_valid_hyps_d list as temporary storage // while (instance_valid_hyps_d.removeFirst(tmp_instance)) { if (tmp_instance != (Instance*)NULL) { Instance::deleteInstance(tmp_instance, true); } } // exit gracefully // return true; } // method: convertLexInstances // // arguments: // DoubleLinkedList& instance_path: (output) best hypothesis instance path // // return: logical error status // // build a graph representing the hypotheses and return it // bool8 HierarchicalSearch::convertLexInstances( DoubleLinkedList& instance_path_a) { // declare local variables // Instance* tmp_instance = (Instance*)NULL; Instance* prev_instance = (Instance*)NULL; Instance* term_instance = (Instance*)NULL; Instance* start_instance = (Instance*)NULL; Instance* end_instance = (Instance*)NULL; GraphVertex* tmp_vertex = (GraphVertex*)NULL; GraphVertex* start_vertex = (GraphVertex*)NULL; GraphVertex* end_vertex = (GraphVertex*)NULL; SearchNode* tmp_node = (SearchNode*)NULL; if (debug_level_d >= Integral::DETAILED) { // debug message // Console::put(L"\nBefore conversion: ---------------------------"); printInstances(instance_path_a); } // store the instances at different levels // int32 num_levels = getNumLevels(); Vector< DoubleLinkedList > inst_levels; Vector< DoubleLinkedList > prev_levels; inst_levels.setLength( num_levels ); prev_levels.setLength( num_levels ); int32 curr_level = 0; int32 prev_level = 0; int32 frame_ind = 0; String out_str; SearchSymbol sym; // find the start and term instances and also set start and end // vertex so that they can be used as marks later. // for (bool8 more_instances = instance_path_a.gotoFirst(); more_instances; more_instances = instance_path_a.gotoNext()) { // if we found the start and end instance, we will use it as mark later // if ( start_instance != NULL && end_instance != NULL ){ break; } tmp_instance = instance_path_a.getCurr(); // get the central vertex from the top of the history stack // GraphVertex* tmp_vertex = (GraphVertex*)NULL; tmp_vertex = tmp_instance->getSymbol()->getCentralVertex(); // check for a NULL vertex // if (tmp_vertex == (GraphVertex*)NULL) { continue; } // set the start instance // if ( tmp_vertex->isStart() ){ start_instance = tmp_instance; start_vertex = tmp_vertex; } // set the end instance // if ( tmp_vertex->isTerm() ){ end_instance = tmp_instance; end_vertex = tmp_vertex; } } // initialize the instance levels and vertex levels // for (int32 i = 0; i < num_levels; i++){ // init the instance levels // DoubleLinkedList* instance_path = new DoubleLinkedList; instance_path->setAllocationMode(DstrBase::USER); instance_path->insertFirst(start_instance); inst_levels.concat(*instance_path); // free allocated memory // delete instance_path; instance_path = (DoubleLinkedList*)NULL; // init the vertex levels // DoubleLinkedList* prev_path = new DoubleLinkedList< Instance >; prev_path->setAllocationMode(DstrBase::USER); prev_levels.concat(*prev_path); // free allocated memory // delete prev_path; prev_path = (DoubleLinkedList*)NULL; } // use the best hypothesis instance path to generate the hypothesis string // for (bool8 more_instances = instance_path_a.gotoFirst(); more_instances; more_instances = instance_path_a.removeFirst(tmp_instance)) { frame_ind = tmp_instance->getFrame(); // get the central vertex from the top of the history stack // tmp_vertex = (GraphVertex*)NULL; tmp_vertex = tmp_instance->getSymbol()->getCentralVertex(); // check for a NULL vertex // if (tmp_vertex == (GraphVertex*)NULL) { continue; } if (tmp_vertex->isTerm()){ term_instance = tmp_instance; continue; } // make sure the vertex is neither the dummy // start nor terminating node // else if ((!tmp_vertex->isStart()) && (!tmp_vertex->isTerm())) { tmp_node = tmp_vertex->getItem(); curr_level = tmp_node->getSearchLevel()->getLevelIndex(); // skip the dummy node // if ( tmp_node->isDummyNode() ){ continue; } // add to the instance list // if ( curr_level == num_levels - 1 ){ inst_levels(curr_level).insertLast(tmp_instance); //prev_levels(curr_level).insertLast(NULL); } // prev instance is lower than current one // else if ( prev_level == curr_level + 1 ){ inst_levels(curr_level).insertLast(tmp_instance); prev_levels(curr_level).insertLast(prev_instance); } // prev instance is term // else if ( term_instance != NULL && curr_level == prev_level ){ inst_levels(curr_level).insertLast(tmp_instance); prev_levels(curr_level).insertLast(term_instance); } } prev_level = curr_level; prev_instance = tmp_instance; term_instance = NULL; } instance_path_a.clear(); instance_path_a.setAllocationMode(DstrBase::SYSTEM); // re-order the instance list // prev_levels(0).gotoFirst(); tmp_instance = new Instance(*start_instance); instance_path_a.insertLast(tmp_instance); frame_ind = 0; // free allocated memory // delete tmp_instance; tmp_instance = (Instance*)NULL; // init the inst and prev levels // for ( int i = 0 ; i < num_levels; i++ ){ inst_levels(i).gotoFirst(); prev_levels(i).gotoFirst(); if (debug_level_d >= Integral::DETAILED) { // debug message // String tmp_string; Long l = i; tmp_string.assign(L"inst_levels: --------------------------- "); tmp_string.concat(l); Console::put(tmp_string); printInstances(inst_levels(i)); tmp_string.assign(L"prev_levels: --------------------------- "); tmp_string.concat(l); Console::put(tmp_string); printInstances(prev_levels(i)); inst_levels(i).gotoFirst(); prev_levels(i).gotoFirst(); } } for (bool8 more_instances = inst_levels(0).gotoFirst(); more_instances; more_instances = inst_levels(0).gotoNext()) { tmp_instance = inst_levels(0).getCurr(); if ( prev_levels(0).length() == 0 ){ prev_instance = (Instance*)NULL; } else{ prev_instance = prev_levels(0).getCurr(); } addToPath(tmp_instance, prev_instance, inst_levels, prev_levels, 0, frame_ind, instance_path_a); prev_levels(0).gotoNext(); } tmp_instance = new Instance(*end_instance); instance_path_a.insertLast(tmp_instance); // free allocated memory // delete tmp_instance; tmp_instance = (Instance*)NULL; if (debug_level_d >= Integral::DETAILED) { // debug message // Console::put(L"\nAfter conversion: ---------------------------"); printInstances(instance_path_a); } // exit gracefully // return true; } // method: addToPath // // arguments: // DoubleLinkedList& instance_path: (output) best hypothesis instance path // // return: logical error status // // build a graph representing the hypotheses and return it // bool8 HierarchicalSearch::addToPath( Instance*& curr_inst_a, Instance*& prev_inst_a, Vector< DoubleLinkedList >& inst_levels, Vector< DoubleLinkedList >& prev_levels, int32 level_num_a, int32& frame_ind_a, DoubleLinkedList& instance_path_a) { // local variable // Instance* tmp_instance = (Instance*)NULL; Instance* prev_instance = (Instance*)NULL; uint32 prev_frame_id = 0; GraphVertex* tmp_vertex = (GraphVertex*)NULL; GraphVertex* prev_vertex = (GraphVertex*)NULL; tmp_instance = new Instance(*curr_inst_a); if ( prev_inst_a == (Instance*)NULL ){ frame_ind_a = tmp_instance->getFrame(); instance_path_a.insertLast(tmp_instance); // free allocated memory // delete tmp_instance; tmp_instance = (Instance*)NULL; // exit gracefully // return true; } tmp_instance->setFrame(frame_ind_a); instance_path_a.insertLast(tmp_instance); // free allocated memory // delete tmp_instance; tmp_instance = (Instance*)NULL; // make sure there is a valid history // prev_frame_id = prev_inst_a->getFrame(); // set the correct vertex // if ( prev_inst_a->getInstanceState() == Instance::PSEUDO_ACTIVE && getSearchLevel(level_num_a + 1 ).getRightContext() > 0 ){ prev_vertex = (GraphVertex*)prev_inst_a->getSkipSymbol(); } else { prev_vertex = prev_inst_a->getSymbol()->getCentralVertex(); } //prev_vertex = tmp_hist->peek()->getCentralVertex(); // for every instance up to the prev_instance // for (bool8 more_instances = inst_levels(level_num_a+1).getCurr(); more_instances && !prev_vertex->isTerm(); more_instances = inst_levels(level_num_a+1).gotoNext()) { tmp_instance = inst_levels(level_num_a+1).getCurr(); if ( prev_levels(level_num_a+1).length() == 0 ){ prev_instance = NULL; } else{ prev_instance = prev_levels(level_num_a+1).getCurr(); } addToPath(tmp_instance, prev_instance, inst_levels, prev_levels, level_num_a+1, frame_ind_a, instance_path_a); // get the central vertex from the top of the history stack // tmp_vertex = (GraphVertex*)NULL; tmp_vertex = tmp_instance->getSymbol()->getCentralVertex(); // debug message // if (debug_level_d >= Integral::ALL) { if ( level_num_a == 0 ){ Long curr_address((uint64)tmp_vertex); Long prev_address((uint64)prev_vertex); curr_address.debug(L"curr_address"); prev_address.debug(L"prev_address"); Long prev_frame(prev_frame_id); Long curr_frame(tmp_instance->getFrame()); prev_frame.debug(L"prev_frame"); curr_frame.debug(L"curr_frame"); } } if ( tmp_vertex == prev_vertex && prev_frame_id <= tmp_instance->getFrame()){ prev_levels(level_num_a+1).gotoNext(); inst_levels(level_num_a+1).gotoNext(); break; } // set to next one // prev_levels(level_num_a+1).gotoNext(); } //inst_levels(level_num_a+1).gotoNext(); // add the term instance // tmp_instance = new Instance(*curr_inst_a); tmp_instance->setFrame(frame_ind_a); instance_path_a.insertLast(tmp_instance); // free allocated memory // delete tmp_instance; tmp_instance = (Instance*)NULL; // exit gracefully // return true; } // method: printInstances // // arguments: // DoubleLinkedList& instance_path: (output) best hypothesis instance path // // return: logical error status // // build a graph representing the hypotheses and return it // bool8 HierarchicalSearch::printInstances( DoubleLinkedList& instance_path_a) { // declare local variables // Instance* tmp_instance = (Instance*)NULL; GraphVertex* tmp_vertex = (GraphVertex*)NULL; SearchNode* tmp_node = (SearchNode*)NULL; int32 curr_level = 0; int32 frame_ind = 0; String out_str; // find the start and term instances and also set start and end // vertex so that they can be used as marks later. // for (bool8 more_instances = instance_path_a.gotoFirst(); more_instances; more_instances = instance_path_a.gotoNext()) { tmp_instance = instance_path_a.getCurr(); // get the central vertex from the top of the history stack // tmp_vertex = (GraphVertex*)NULL; tmp_vertex = tmp_instance->getSymbol()->getCentralVertex(); // check for a NULL vertex // if (tmp_vertex == (GraphVertex*)NULL) { continue; } // make sure the vertex is neither the dummy // start nor terminating node // else if ((!tmp_vertex->isStart()) && (!tmp_vertex->isTerm())) { tmp_node = tmp_vertex->getItem(); curr_level = tmp_node->getSearchLevel()->getLevelIndex(); frame_ind = tmp_instance->getFrame(); // print the context // String context; tmp_instance->getSymbol()->print(context); out_str.assign(context); out_str.concat(L" level:"); out_str.concat(curr_level); out_str.concat(L" frame:"); out_str.concat(frame_ind); Console::put(out_str); } } // exit gracefully // return true; }