// file: $isip/class/search/HierarchicalSearch/hsrch_12.cc // version: $Id: hsrch_12.cc 9329 2003-10-29 20:40:03Z alphonso $ // // isip include files // #include "HierarchicalSearch.h" // method: ascend // // arguments: // Instance* instance: (input) input instance // // return: logical error status // // this method saves the current symbol in the symbol stack before // replacing it with the symbol on the history stack // bool8 HierarchicalSearch::ascend(Instance* instance_a) { // declare local variables // Context* symbol = (Context*)NULL; History* history = (History*)NULL; History* symbol_stack = (History*)NULL; // make sure the instance is valid // if (instance_a == (Instance*)NULL) { return Error::handle(name(), L"ascend - instance is null", Error::ARG, __FILE__, __LINE__); } // if the symbol is null then we cannot ascend // symbol = instance_a->getSymbol(); if (symbol == (Context*)NULL) { return Error::handle(name(), L"ascend - symbol is null", Error::ARG, __FILE__, __LINE__); } // output the debugging information // if (debug_level_d >= Integral::ALL) { symbol->print(); } // if the history stack is empty or null then we cannot ascend any further // history = instance_a->getHistory(); if (history == (History*)NULL) { return Error::handle(name(), L"ascend - history is null", Error::ARG, __FILE__, __LINE__); } if (history->isEmpty()) { return true; } // output the debugging information // if (debug_level_d >= Integral::ALL) { if (!history->isEmpty()) { history->peek()->print(); } } // if the symbol stack is null then we cannot ascend // symbol_stack = instance_a->getSymbolStack(); if (symbol_stack == (History*)NULL) { return Error::handle(name(), L"ascend - symbol stack is empty", Error::ARG, __FILE__, __LINE__); } // output the debugging information // if (debug_level_d >= Integral::ALL) { if (!symbol_stack->isEmpty()) { symbol_stack->peek()->print(); } } // push the current symbol on the symbol stack // symbol_stack = history_pool_d.pushAndAllocate(symbol_stack, symbol); // output the debugging information // if (debug_level_d >= Integral::ALL) { if (!symbol_stack->isEmpty()) { symbol_stack->peek()->print(); } } // has the history been previously generated? // if so reuse the history, // if not generate a new history and add it to the history pool // instance_a->setSymbolStack(symbol_stack); // move the symbol on top of the history to the current symbol // history = history_pool_d.popAndAllocate(history, symbol); // output the debugging information // if (debug_level_d >= Integral::ALL) { if (!history->isEmpty()) { history->peek()->print(); } } // the context must exist in the context pool in this case // instance_a->setSymbol(symbol); // output the debugging information // if (debug_level_d >= Integral::ALL) { instance_a->getSymbol()->print(); } // has the history been previously generated? // if so reuse the history, // if not generate a new history and add it to the history pool // instance_a->setHistory(history); // exit gracefully // return true; } // method: descend // // arguments: // Instance* instance: (input) input instance // // return: logical error status // // this method saves the current symbol in the symbol stack before // replacing it with the symbol on the history stack // bool8 HierarchicalSearch::descend(Instance* instance_a) { // declare local variables // Context* symbol = (Context*)NULL; History* history = (History*)NULL; History* symbol_stack = (History*)NULL; // make sure the instance is valid // if (instance_a == (Instance*)NULL) { return Error::handle(name(), L"descend - instance is null", Error::ARG, __FILE__, __LINE__); } // if the symbol is null then we cannot descend // symbol = instance_a->getSymbol(); if (symbol == (Context*)NULL) { return Error::handle(name(), L"descend - symbol is null", Error::ARG, __FILE__, __LINE__); } // output the debugging information // if (debug_level_d >= Integral::ALL) { symbol->print(); } // if the history stack null then we cannot descend any further // history = instance_a->getHistory(); if (history == (History*)NULL) { return Error::handle(name(), L"descend - history is null", Error::ARG, __FILE__, __LINE__); } // output the debugging information // if (debug_level_d >= Integral::ALL) { if (!history->isEmpty()) { history->peek()->print(); } } // if the symbol stack is null or empty then we cannot descend // symbol_stack = instance_a->getSymbolStack(); if (symbol_stack == (History*)NULL) { return Error::handle(name(), L"descend - symbol stack is empty", Error::ARG, __FILE__, __LINE__); } if (symbol_stack->isEmpty()) { return true; } // output the debugging information // if (debug_level_d >= Integral::ALL) { if (!symbol_stack->isEmpty()) { symbol_stack->peek()->print(); } } // push the current symbol on the history stack // history = history_pool_d.pushAndAllocate(history, symbol); // output the debugging information // if (debug_level_d >= Integral::ALL) { if (!history->isEmpty()) { history->peek()->print(); } } // has the history been previously generated? // if so reuse the history, // if not generate a new history and add it to the history pool // instance_a->setHistory(history); // move the symbol on top of the symbol stack to the current symbol // symbol_stack = history_pool_d.popAndAllocate(symbol_stack, symbol); // output the debugging information // if (debug_level_d >= Integral::ALL) { if (!symbol_stack->isEmpty()) { symbol_stack->peek()->print(); } } // the context must exist in the context pool in this case // instance_a->setSymbol(symbol); // has the history been previously generated? // if so reuse the history, // if not generate a new history and add it to the history pool // instance_a->setSymbolStack(symbol_stack); // exit gracefully // return true; } // method: generateRightContexts // // arguments: // DoubleLinkedList& context_list: (output) list of next contexts // DoubleLinkedList& score: (output) transition probabilities // const Context* initial_context: (input) initial context to start from // int32 depth: (input) right context length // int32 level: (input) current search level // // return: logical error status // // generate a list of contexts expanded from the starting context to right // into the context depth // bool8 HierarchicalSearch::generateRightContexts( DoubleLinkedList& context_list_a, DoubleLinkedList& score_list_a, Context* initial_context_a, int32 depth_a, int32 level_a) { // declare local variables // Float* new_score = (Float*)NULL; Float* curr_score = (Float*)NULL; Context* new_context = (Context*)NULL; Context* curr_context = (Context*)NULL; context_list_a.insertLast(initial_context_a); score_list_a.insertLast(new Float(0.0)); // genrate new context lists into the depht of depth_a // for (int32 i = 0; i < depth_a; i++) { // all new contexts will be added at the end of the list so we set // the mark to tell us when to stop propagating // context_list_a.gotoLast(); context_list_a.setMark(); context_list_a.gotoFirst(); score_list_a.gotoLast(); score_list_a.setMark(); score_list_a.gotoFirst(); // propagate all contexts in the list // bool8 end_loop = context_list_a.length() < 1; while (!end_loop) { end_loop = (context_list_a.isMarkedElement() & score_list_a.isMarkedElement()); // get the current context from the list // context_list_a.removeFirst(curr_context); score_list_a.removeFirst(curr_score); // get the last vertex of the current context // GraphVertex* curr_vertex = curr_context->getLastVertex(); // if it is NULL vertex, throw an error and exit // if (curr_vertex == (GraphVertex*)NULL) { return Error::handle(name(), L"generateRightContexts - from NULL!", Error::ARG, __FILE__, __LINE__); } if (!curr_vertex->isTerm()) { // loop over arcs of the last vertex if it is not terminal vertex // for (bool8 more_arcs = curr_vertex->gotoFirst(); more_arcs; more_arcs = curr_vertex->gotoNext()) { // determine the symbol insertion penalty and transition // scale factor // float32 tr_scale = getSearchLevel(level_a).getTrScale(); float32 symbol_penalty = getSearchLevel(level_a).getSymbolPenalty(); // shift next context // new_score = new Float(*curr_score); new_context = context_pool_d.shiftAndAllocate(curr_context, curr_vertex->getCurr()->getVertex()); // update the score with the arc score // int32 symbol_id = curr_vertex->getItem()->getSymbolId(); if (!getSearchLevel(level_a).isDummySymbol(symbol_id) && !getSearchLevel(level_a).isSPenaltyExcludeSymbol(symbol_id)) { new_score->add((curr_vertex->getCurr()->getWeight() * tr_scale) + symbol_penalty); } else { new_score->add(curr_vertex->getCurr()->getWeight()); } // add new context to the list // context_list_a.insertLast(new_context); score_list_a.insertLast(new_score); } // end of loop over all arcs of the last vertex // delete the current context from the list, since we have // propagated from it // delete curr_score; } // end of if not terminal // if the last vertex of the current context is terminal, simply // shift context // else { curr_context = context_pool_d.shiftAndAllocate(curr_context, curr_vertex); context_list_a.insertLast(curr_context); score_list_a.insertLast(curr_score); } // end of else terminal vertex context_list_a.gotoFirst(); score_list_a.gotoFirst(); } // end of the loop over contexts list } // end of for depths loop //exit gracefully // return true; } // method: initializeRightContexts // // arguments: // Instance* curr_instance: (input) initial instance to start from // Context& init_context: (input) initial context to start from // float32 curr_weight: (input) transition probability // int32 depth: (input) right context length // // return: logical error status // // generate a list of contexts expanded from the starting context to right // into the context depth // bool8 HierarchicalSearch::initializeRightContexts(Instance* curr_instance_a, Context& init_context_a, int32 level_num_a, float32 curr_weight_a, int32 depth_a) { // declare local variables // Float* next_score = (Float*)NULL; Instance* next_instance = (Instance*)NULL; DoubleLinkedList inst_list(DstrBase::USER); DoubleLinkedList score_list(DstrBase::USER); // set up the initial instance // if (curr_instance_a == (Instance*)NULL) { // create a new instance // next_instance = new Instance(); next_instance->setFrame((ulong)current_frame_d); if (search_mode_d == TRAIN) { next_instance->setInstanceMode(Instance::TRAIN); } // has the history been previously generated? if so reuse the history, // if not generate a new history and add it to the history pool // next_instance->setHistory(history_pool_d.initAndAllocate()); next_instance->setSymbolStack(history_pool_d.initAndAllocate()); // initialize the structure that holds the n-symbols // initializeNsymbolInstance(next_instance); } else { // create a new instance // next_instance = new Instance(*curr_instance_a); next_instance->setFrame((ulong)current_frame_d); } // output the debugging information // if (debug_level_d >= Integral::ALL) { init_context_a.print(); } // has the context been previously generated? if so reuse the context, // if not generate a new context and add it to the context pool // next_instance->setSymbol(context_pool_d.get(init_context_a)); // generate right contexts for the instance // inst_list.insertLast(next_instance); lookAhead(level_num_a, depth_a, inst_list, score_list); // generate a new instance for each right context // for (bool8 more_items = (inst_list.gotoFirst() && score_list.gotoFirst()); more_items; more_items = (inst_list.gotoNext() && score_list.gotoNext())) { // retrieve the current instance // next_score = score_list.getCurr(); next_instance = inst_list.getCurr(); // add the instance to the search node's instance list // if (!addHypothesisPath(next_instance, curr_instance_a, level_num_a, *next_score)) { return Error::handle(name(), L"initializeRightContexts", Error::ARG, __FILE__, __LINE__); } } // free allocated memory // score_list.setAllocationMode(DstrBase::SYSTEM); score_list.clear(); // exit gracefully // return true; } // method: isTerminal // // arguments: // Instance* curr_instance: (input) instance in hypotheses space // int32 level_num: (input) current level number // // return: logical error status // // method determines if the instance has reached the end of the subgraph // bool8 HierarchicalSearch::isTerminal(Instance* curr_instance_a, int32 level_num_a) { // declare local variables // GraphVertex* next_vertex = (GraphVertex*)NULL; GraphVertex* central_vertex = (GraphVertex*)NULL; GraphVertex* skip_vertex = (GraphVertex*)NULL; // when the internal state of the instance is pseudo-active // if (curr_instance_a->getInstanceState() == Instance::PSEUDO_ACTIVE) { // when the skip vertex is not adjacent from the central vertex then the // current instance is at the end of the subgraph // if ((int32)curr_instance_a->getSkipLevel() == level_num_a) { skip_vertex = (GraphVertex*)curr_instance_a->getSkipSymbol(); central_vertex = curr_instance_a->getSymbol()->getCentralVertex(); if (!central_vertex->isAdjacent(skip_vertex)) { return true; } } // return the status // return false; } // retrieve the central vertex // central_vertex = curr_instance_a->getSymbol()->getCentralVertex(); if (central_vertex == (GraphVertex*)NULL) { return Error::handle(name(), L"isTerminal - central vertex is null", Error::ARG, __FILE__, __LINE__); } // retrieve the vertex that will be shifted into central vertex // next_vertex = curr_instance_a->getSymbol()->getAfterCentralVertex(); if (next_vertex == (GraphVertex*)NULL) { return Error::handle(name(), L"isTerminal - next vertex is null", Error::ARG, __FILE__, __LINE__); } // when the next vertex is not adjacent from the central vertex then the // current instance is at the end of the subgraph // if (!central_vertex->isAdjacent(next_vertex)) { return true; } // return the status // return false; } // method: extendRightContexts // // arguments: // Instance* curr_instance: (input) initial instance to start from // int32 level_num: (input) level number in the hierarchy // // return: logical error status // // generate a list of contexts expanded from the starting context to right // into the context depth // bool8 HierarchicalSearch::extendRightContexts(Instance* curr_instance_a, int32 level_num_a, Context* prev_symbol_a) { // declare local variables // Float* next_score = (Float*)NULL; Instance* next_instance = (Instance*)NULL; DoubleLinkedList inst_list(DstrBase::USER); DoubleLinkedList score_list(DstrBase::USER); // create a new instance // next_instance = new Instance(*curr_instance_a); next_instance->setFrame((ulong)current_frame_d); // set the current symbol if it is valid // if (prev_symbol_a != (Context*)NULL) { next_instance->setSymbol(prev_symbol_a); } // generate right contexts for the instance // inst_list.insertLast(next_instance); lookAhead(level_num_a, 1, inst_list, score_list); // generate a new instance for each right context // for (bool8 more_items = (inst_list.gotoFirst() && score_list.gotoFirst()); more_items; more_items = (inst_list.gotoNext() && score_list.gotoNext())) { // retrieve the current instance // next_score = score_list.getCurr(); next_instance = inst_list.getCurr(); // add the instance to the search node's instance list // if (!addHypothesisPath(next_instance, curr_instance_a, level_num_a, *next_score)) { return Error::handle(name(), L"extendRightContexts", Error::ARG, __FILE__, __LINE__); } } // free allocated memory // score_list.setAllocationMode(DstrBase::SYSTEM); score_list.clear(); // exit gracefully // return true; } // method: printHistory // // arguments: // const History* history: (input) history of the instance // // return: logical error status // bool8 HierarchicalSearch::printHistory(const History* history_a) { // declare local variables // bool8 more = false; // save the current state // const_cast(history_a)->setMark(); // print each level of the history // for (more = const_cast(history_a)->gotoFirst(); more; more = const_cast(history_a)->gotoNext()) { const_cast(history_a)->getCurr()->print(); } // restore the saved state // const_cast(history_a)->gotoMark(); // exit gracefully // return true; } // method: propagateUp // // arguments: // int32 curr_level: (input) current level in the hierarchy // int32 level: (input) level in the hierarchy we started at // int32 curr_depth: (input) current right context length // int32 depth: (input) desired right context length // DoubleLinkedList& inst_list: (output) new instances generated // DoubleLinkedList& curr_hist: (input) working history // DoubleLinkedList& prev_hist: (input) working history // DoubleLinkedList& score: (output) transition probabilities // // return: logical error status // // method propagates up the search hoerarchy in the process of generating // right context in cross-word decoding // bool8 HierarchicalSearch::propagateUp( int32 curr_level_a, int32 level_a, int32 curr_depth_a, int32 depth_a, DoubleLinkedList& inst_list_a, DoubleLinkedList& curr_hist_a, DoubleLinkedList& prev_hist_a, DoubleLinkedList& score_a) { // when we are at the top most level we cannot go up the hiererchy // if (curr_level_a == (int32)initial_level_d) { return false; } // ascend to the previous level in the hierarchy and look across symbols // else { // pop the current stack context and push it into the previous stack // Context* symbol = curr_hist_a.getCurr()->pop(); prev_hist_a.getCurr()->push(symbol); ascend(inst_list_a.getCurr()); // output the debugging information // if (debug_level_d >= Integral::ALL) { inst_list_a.getCurr()->getSymbol()->print(); } // recursively call the lookahead helper - decrement the current level // if (!lookAheadHelper((GraphVertex*)NULL, curr_level_a-1, level_a, curr_depth_a, depth_a, inst_list_a, curr_hist_a, prev_hist_a, score_a)) { return false; } } // return the status // return true; } // method: propagateDown // // arguments: // Context* symbol: (input) initial context to start with // Context* symbol1: (input) working initial context // GraphVertex* curr_vertex: (input) initial graph vertex // int32 curr_level: (input) current level in the hierarchy // int32 level: (input) level in the hierarchy we started at // int32 curr_depth: (input) current right context length // int32 depth: (input) desired right context length // DoubleLinkedList& inst_list: (output) new instances generated // DoubleLinkedList& curr_hist: (input) working history // DoubleLinkedList& prev_hist: (input) working history // DoubleLinkedList& score: (output) transition probabilities // // return: logical error status // // method propagates down the search hoerarchy in the process of generating // right context in cross-word decoding // bool8 HierarchicalSearch::propagateDown( Context* symbol_a, Context* symbol1_a, GraphVertex* curr_vertex_a, int32 curr_level_a, int32 level_a, int32 curr_depth_a, int32 depth_a, DoubleLinkedList& inst_list_a, DoubleLinkedList& curr_hist_a, DoubleLinkedList& prev_hist_a, DoubleLinkedList& score_a) { // declare local variables // GraphVertex* start_vertex = (GraphVertex*)NULL; if ((symbol_a == (Context*)NULL) || (symbol1_a == (Context*)NULL)) { return Error::handle(name(), L"propagateDown", Error::ARG, __FILE__, __LINE__); } // we cannot propagate down if the current level is equal to the level // if (curr_level_a == level_a) { return false; } // generate the context to index the subgraph at the lower level // SearchLevel& sl_curr = getSearchLevel(curr_level_a); SearchLevel& sl_lower = getSearchLevel(curr_level_a+1); Context* symbol = symbol_a; if (!symbol->getLastVertex()->isTerm()) { symbol = context_pool_d.extendAndAllocate(symbol, curr_vertex_a); } // output the debugging information // if (debug_level_d >= Integral::ALL) { symbol->print(); } Context* symbol1 = symbol1_a; symbol1 = context_pool_d.shiftAndAllocate(symbol1, curr_vertex_a); // shift the history at the current level // Context* tmp_symbol = inst_list_a.getCurr()->getSymbol(); inst_list_a.getCurr()->setSymbol(symbol); Context* tmp_symbol1 = curr_hist_a.getCurr()->pop(); curr_hist_a.getCurr()->push(symbol1); // retrieve the subgraph at the lower level // Context* conv_context = (Context*)NULL; symbol1->convert(conv_context); Ulong* subgr_ind = sl_curr.getSubGraphIndex(*conv_context); if (conv_context != (Context*)NULL) { delete conv_context; } // make sure we have a valid subgraph index // if (subgr_ind == (Ulong*)NULL) { // restore the history stach to its previous state // inst_list_a.getCurr()->setSymbol(tmp_symbol); symbol1 = curr_hist_a.getCurr()->pop(); curr_hist_a.getCurr()->push(tmp_symbol1); return false; } // get the start vertex of the subgraph // start_vertex = (sl_lower.getSubGraph((int32)*subgr_ind)).getStart(); // insert the history at the next level // tmp_symbol1 = prev_hist_a.getCurr()->pop(); curr_hist_a.getCurr()->push(tmp_symbol1); descend(inst_list_a.getCurr()); // recursively call the lookahead helper - incerment the current level // if (!lookAheadHelper(start_vertex, curr_level_a+1, level_a, curr_depth_a, depth_a, inst_list_a, curr_hist_a, prev_hist_a, score_a)) { return false; } // return the status // return true; } // method: lookAhead // // arguments: // int32 level: (input) level in the hierarchy we started at // int32 depth: (input) desired right context length // DoubleLinkedList& inst_list: (output) instances generated // DoubleLinkedList& score: (output) transition probabilities // // return: logical error status // // method propagates up and down the search hoerarchy in the process of // generating right context in corss-word decoding // bool8 HierarchicalSearch::lookAhead(int32 level_a, int32 depth_a, DoubleLinkedList& inst_list_a, DoubleLinkedList& score_a) { // declare local variables // History* init_history = (History*)NULL; Instance* init_instance = (Instance*)NULL; GraphVertex* init_vertex = (GraphVertex*)NULL; DoubleLinkedList curr_hist(DstrBase::USER); DoubleLinkedList prev_hist(DstrBase::USER); // make sure the instance list is not empty // if (inst_list_a.isEmpty()) { return false; } init_instance = inst_list_a.getFirst(); if (init_instance == (Instance*)NULL) { return Error::handle(name(), L"lookAhead", Error::ARG, __FILE__, __LINE__); } // make sure the symbol associated with the instance is not null // if (init_instance->getSymbol() == (Context*)NULL) { return Error::handle(name(), L"lookAhead", Error::ARG, __FILE__, __LINE__); } // when the internal state of the instance is pseudo-active // if ((init_instance->getInstanceState() == Instance::PSEUDO_ACTIVE) && (init_instance->getSkipLevel() == (ulong)level_a)) { // swap the contexts // ulong skip_symbol = init_instance->getSkipSymbol(); GraphVertex* tmp_vertex = init_instance->getSymbol()->getCentralVertex(); init_instance->setSymbol(context_pool_d.setCentralAndAllocate(init_instance->getSymbol(), (GraphVertex*)skip_symbol)); init_instance->setSkipSymbol((ulong)tmp_vertex); // set the internal state for the instance to active // score_a.insertLast(new Float(0.0)); init_instance->setInstanceState(Instance::ACTIVE); // exit gracefully // return true; } // when the internal state of the instance is active // if ((init_instance->getInstanceState() == Instance::ACTIVE) && (init_instance->getSkipLevel() == (ulong)level_a)) { // setup the context for the instance // ulong tmp_symbol = init_instance->getSkipSymbol(); init_instance->setSymbol(context_pool_d.setCentralAndAllocate(init_instance->getSymbol(), (GraphVertex*)tmp_symbol)); // set the internal state for the instance to inactive // init_instance->setInstanceState(Instance::INACTIVE); } // output the debugging information // if (debug_level_d >= Integral::ALL) { // print the symbol // init_instance->getSymbol()->print(); // print the history // if (init_instance->getHistory() != (History*)NULL) { printHistory(init_instance->getHistory()); } // print the symbol stack // if (init_instance->getSymbolStack() != (History*)NULL) { printHistory(init_instance->getSymbolStack()); } } // get the history associated with the instance // init_history = new History(*init_instance->getHistory()); init_history->push(init_instance->getSymbol()); // initialize the lists before generating the right context // score_a.insertLast(new Float(0.0)); curr_hist.insertLast(new History(*init_history)); prev_hist.insertLast(new History()); // initialize the vertices // init_vertex = init_instance->getSymbol()->getLastVertex(); // generate right context for the central vertex // lookAheadHelper(init_vertex, level_a, level_a, 0, depth_a, inst_list_a, curr_hist, prev_hist, score_a); // free allocated memory // delete init_history; init_history = (History*)NULL; curr_hist.setAllocationMode(DstrBase::SYSTEM); curr_hist.clear(); prev_hist.setAllocationMode(DstrBase::SYSTEM); prev_hist.clear(); // exit gracefully // return true; } // method: lookAheadHelper // // arguments: // GraphVertex* curr_vertex: (input) initial graph vertex // int32 curr_level: (input) current level in the hierarchy // int32 level: (input) level in the hierarchy we started at // int32 curr_depth: (input) current right context length // int32 depth: (input) desired right context length // DoubleLinkedList& inst_list: (output) new instances generated // DoubleLinkedList& curr_hist: (input) working history // DoubleLinkedList& prev_hist: (input) working history // DoubleLinkedList& score: (output) transition probabilities // // return: logical error status // // method propagates up and down the search hoerarchy in the process of // generating right context in corss-word decoding // bool8 HierarchicalSearch::lookAheadHelper( GraphVertex* curr_vertex_a, int32 curr_level_a, int32 level_a, int32 curr_depth_a, int32 depth_a, DoubleLinkedList& inst_list_a, DoubleLinkedList& curr_hist_a, DoubleLinkedList& prev_hist_a, DoubleLinkedList& score_a) { // declare local variables // GraphVertex* next_vertex = (GraphVertex*)NULL; // when the current depth is equal to the requires depth we are done // if (curr_depth_a == depth_a) { return true; } // when we are at the level needed to generate right context // if (curr_level_a == level_a) { // when the current context has a right context length of zero and it // has an extension, i.e., the context has been previously extended // if (inst_list_a.getCurr()->getSymbol()->isExtended()) { Context* symbol = inst_list_a.getCurr()->getSymbol(); symbol = context_pool_d.foldAndAllocate(symbol); inst_list_a.getCurr()->setSymbol(symbol); // output the debugging information // if (debug_level_d >= Integral::ALL) { inst_list_a.getCurr()->getSymbol()->print(); } return true; } // when the current vertex is a term - shift the context // if (curr_vertex_a->isTerm()) { Context* symbol = curr_hist_a.getCurr()->pop(); symbol = context_pool_d.shiftAndAllocate(symbol, curr_vertex_a); curr_hist_a.getCurr()->push(symbol); inst_list_a.getCurr()->setSymbol(symbol); // output the debugging information // if (debug_level_d >= Integral::ALL) { inst_list_a.getCurr()->getSymbol()->print(); } return true; } // loop over all next vertices of the current vertex // int32 index = 0; Float* curr_score = new Float(*score_a.getCurr()); History* prev_history = new History(*prev_hist_a.getCurr()); History* curr_history = new History(*curr_hist_a.getCurr()); Instance* curr_instance = new Instance(*inst_list_a.getCurr()); for (bool8 more = curr_vertex_a->gotoFirst(); more; more = curr_vertex_a->gotoNext(), index++) { // make sure each next vertex has a unique history // if (index > 0) { score_a.insertLast(new Float(*curr_score)); curr_hist_a.insertLast(new History(*curr_history)); prev_hist_a.insertLast(new History(*prev_history)); inst_list_a.insertLast(new Instance(*curr_instance)); } // retrieve the next vertex // next_vertex = curr_vertex_a->getCurr()->getVertex(); // determine the transition scale factor for the current level // int32 symbol_id = next_vertex->getItem()->getSymbolId(); float32 tr_scale = getSearchLevel(level_a).getTrScale(); float32 symbol_penalty = getSearchLevel(level_a).getSymbolPenalty(); // update the transition score // float32 trans_score = curr_vertex_a->getCurr()->getWeight() * tr_scale; score_a.getCurr()->assign(*(score_a.getCurr()) + trans_score); // when the next vertex is NOT a term node - stay at the same level // if (!next_vertex->isTerm()) { // update the score // if (!getSearchLevel(level_a).isDummySymbol(symbol_id) && !getSearchLevel(level_a).isSPenaltyExcludeSymbol(symbol_id)) { inst_list_a.getCurr()->setScore(inst_list_a.getCurr()->getScore() + symbol_penalty); } // when the next vertex is a skip symbol // if (getSearchLevel(level_a).isSkipSymbol(symbol_id)) { // set the internal state for the instance to pseudo-active // inst_list_a.getCurr()->setInstanceState(Instance::PSEUDO_ACTIVE); // save the skip symbol for later retrieval // inst_list_a.getCurr()->setSkipLevel((ulong)level_a); inst_list_a.getCurr()->setSkipSymbol((ulong)next_vertex); // recursively call the lookahead helper - incerment the depth // lookAheadHelper(next_vertex, curr_level_a, level_a, curr_depth_a, depth_a, inst_list_a, curr_hist_a, prev_hist_a, score_a); } // when the next vertex is not a skip symbol // else { // shift the right context of the symbol into the current context // Context* symbol = curr_hist_a.getCurr()->pop(); symbol = context_pool_d.shiftAndAllocate(symbol, next_vertex); curr_hist_a.getCurr()->push(symbol); inst_list_a.getCurr()->setSymbol(symbol); // output the debugging information // if (debug_level_d >= Integral::ALL) { symbol->print(); } // recursively call the lookahead helper - incerment the depth // lookAheadHelper(next_vertex, curr_level_a, level_a, curr_depth_a+1, depth_a, inst_list_a, curr_hist_a, prev_hist_a, score_a); } } // when the next vertex is a terminal node - ascend one level // else { // ascend to the previous level in the hierarchy // if (!propagateUp(curr_level_a, level_a, curr_depth_a, depth_a, inst_list_a, curr_hist_a, prev_hist_a, score_a)) { // restore the original contents of the current list // while (!prev_hist_a.getCurr()->isEmpty()) { descend(inst_list_a.getCurr()); Context* symbol = prev_hist_a.getCurr()->pop(); curr_hist_a.getCurr()->push(symbol); // output the debugging information // if (debug_level_d >= Integral::ALL) { symbol->print(); } } // shift !NO_RIGHT_CONTEXT for the required depth // for (int i=curr_depth_a; ipop(); symbol = context_pool_d.shiftAndAllocate(symbol, next_vertex); curr_hist_a.getCurr()->push(symbol); inst_list_a.getCurr()->setSymbol(symbol); } // free allocated memory // delete curr_score; delete prev_history; delete curr_history; delete curr_instance; // exit gracefully // return true; } } } // free allocated memory // delete curr_score; delete prev_history; delete curr_history; delete curr_instance; } // when we are NOT at the level needed to generate right context // else { // make a copy of the current context // Context* symbol = inst_list_a.getCurr()->getSymbol(); Context* symbol1 = curr_hist_a.getCurr()->peek(); // output the debugging information // if (debug_level_d >= Integral::ALL) { symbol->print(); } if (curr_vertex_a == (GraphVertex*)NULL) { curr_vertex_a = symbol->getLastVertex(); } // when the current vertex is a terminal we cannot proceed further // if (curr_vertex_a->isTerm()) { return false; } // loop over all next vertices of the current vertex // int32 index = 0; Float* curr_score = new Float(*score_a.getCurr()); History* prev_history = new History(*prev_hist_a.getCurr()); History* curr_history = new History(*curr_hist_a.getCurr()); Instance* curr_instance = new Instance(*inst_list_a.getCurr()); for (bool8 more=curr_vertex_a->gotoFirst(); more; more=curr_vertex_a->gotoNext(), index++) { // make sure each next vertex has a unique history // if (index > 0) { score_a.insertLast(new Float(*curr_score)); curr_hist_a.insertLast(new History(*curr_history)); prev_hist_a.insertLast(new History(*prev_history)); inst_list_a.insertLast(new Instance(*curr_instance)); } // retrieve the next vertex // next_vertex = curr_vertex_a->getCurr()->getVertex(); // determine the transition scale factor for the current level // float32 tr_scale = getSearchLevel(level_a).getTrScale(); // update the transition score // float32 trans_score = curr_vertex_a->getCurr()->getWeight() * tr_scale; score_a.getCurr()->assign(*(score_a.getCurr()) + trans_score); // when the next vertex is NOT a term node - descend one level // if (!next_vertex->isTerm()) { // descend to the next level in the hierarchy // if (!propagateDown(symbol, symbol1, next_vertex, curr_level_a, level_a, curr_depth_a, depth_a, inst_list_a, curr_hist_a, prev_hist_a, score_a)) { // free allocated memory // delete curr_score; delete prev_history; delete curr_history; delete curr_instance; // exit gracefully // return false; } } // when the next vertex is a terminal node - ascend one level // else { // ascend to the previous level in the hierarchy // if (!propagateUp(curr_level_a, level_a, curr_depth_a, depth_a, inst_list_a, curr_hist_a, prev_hist_a, score_a)) { // retrieve the current context // Context* symbol = inst_list_a.getCurr()->getSymbol(); Context* symbol1 = curr_hist_a.getCurr()->peek(); // descend to the next level in the hierarchy // if (!propagateDown(symbol, symbol1, next_vertex, curr_level_a, level_a, curr_depth_a, depth_a, inst_list_a, curr_hist_a, prev_hist_a, score_a)) { // pop the previous stack context and push into the current stack // descend(inst_list_a.getCurr()); Context* symbol = prev_hist_a.getCurr()->pop(); curr_hist_a.getCurr()->push(symbol); // free allocated memory // delete curr_score; delete prev_history; delete curr_history; delete curr_instance; // exit gracefully // return false; } } } } // free allocated memory // delete curr_score; delete prev_history; delete curr_history; delete curr_instance; } // exit gracefully // return true; }