// file: $isip/class/search/Context/cont_05.cc // version: $Id: cont_05.cc 9029 2003-02-15 17:08:33Z alphonso $ // // isip include files // #include "Context.h" // method: assign // // arguments: // const Context& copy_context: (input) context to copy // // return: logical error status // // assign context from the copy // bool8 Context::assign(const Context& copy_context_a) { // clear the contents // clear(); // copy all internal data // CircularDelayLine::assign(copy_context_a); central_d = copy_context_a.central_d; ext_length_d = copy_context_a.ext_length_d; // exit gracefully // return true; } // method: eq // // arguments: // const Context& context: (input) Context object to compare // // return: a bool8 value indicating status // // this method checks if the input object is the same as the current one // bool8 Context::eq(const Context& context_a) const { // get the context length // int32 len = length(); // check to see if the context lengths are the same // if (len == context_a.length()) { for (int32 i = 0; i < len; i++) { if ((*this)(i) != context_a(i)) { return false; } } } else { return false; } // if we reached this far then the items must be identical // return true; } // method: hash // // arguments: // int32 capacity: (input) upper bound on the hash value // // return: an index to the hash table of model indices // // this is the hash method // hash key is an array of symbol indices, hashed item is an index of // lower level model for this context symbol sequence // Note: if the context contains array of pointers to graph vertices, // we need to convert them to symbol indices before hashing (using // the convert() method) // int32 Context::hash(int32 capacity_a) const { // declare local values // ulong hash_index = (ulong)0; for (int32 i = v_d.length(); i > 0; i--) { ulong index = (ulong)(*this)(-i); hash_index = (hash_index << 5) ^ (hash_index >> 27) ^ index; } hash_index = (ulong)(hash_index % (capacity_a - 1)); // return the hash index // return hash_index; } // method: print // // arguments: // String& output: (output) string of context symbols (e.g. "a-b+c") // // return: logical error status // // this method prints the comment and context symbols left context // symbols are followed by "-" right context symbols follow "+" // bool8 Context::print(String& output_a) { // declare local variables // SearchSymbol symbol; // loop over all context vertices // for (int32 i = length(); i > 0 ; i--) { // get the pointer to the graph vertex // GVSnode* vertex = (GVSnode*)(ulong)(*this)(-i); // get the symbol corresponding to the graph vertex // if (vertex == (GVSnode*)NULL) { output_a.concat(L"null vertex!"); } else if (vertex->isStart()) { output_a.concat(SearchSymbol::NO_LEFT_CONTEXT); } else if (vertex->isTerm()) { output_a.concat(SearchSymbol::NO_RIGHT_CONTEXT); } else { vertex->getItem()->getSymbol(symbol); output_a.concat(symbol); } // distinguish the left, right and extended context symbols // if (i > (central_d + ext_length_d)) { output_a.concat(L"-"); } else if (i > (1 + ext_length_d)) { output_a.concat(L"+"); } else if (i > 1) { output_a.concat(L"|"); } } // exit gracefully // return true; } // method: print // // arguments: none // // return: logical error status // // this method prints the comment and context symbols left context // symbols are followed by "-" right context symbols follow "+" // bool8 Context::print() { // declare local variables // String output; SearchSymbol symbol; // appeand the initial comment // output.concat(L"context: "); // loop over all context vertices // for (int32 i = length(); i > 0 ; i--) { // get the pointer to the graph vertex // GVSnode* vertex = (GVSnode*)(ulong)(*this)(-i); // get the symbol corresponding to the graph vertex // if (vertex == (GVSnode*)NULL) { output.concat(L"null vertex!"); } else if (vertex->isStart()) { output.concat(SearchSymbol::NO_LEFT_CONTEXT); } else if (vertex->isTerm()) { output.concat(SearchSymbol::NO_RIGHT_CONTEXT); } else { vertex->getItem()->getSymbol(symbol); output.concat(symbol); } // distinguish the left, right and extended context symbols // if (i > (central_d + ext_length_d)) { output.concat(L"-"); } else if (i > (1 + ext_length_d)) { output.concat(L"+"); } else if (i > 1) { output.concat(L"|"); } } // print the context // Console::put(output); // exit gracefully // return true; } // method: convert // // arguments: none // // return: a bool8 value indicating status // // this method converts pointers to graph vertices in this context to // search symbol indices (not reversible) // bool8 Context::convert() { // get the indices of all search symbols from the vertices // for (int32 i = 0; i < length(); i++) { GVSnode* vertex = (GVSnode*)(ulong)v_d(i); // check for the NULL vertex // if (vertex == (GVSnode*)NULL) { vertex = getCentralVertex()->getItem()->getSearchLevel()-> getSubGraph((int32)0).getTerm(); } // get the symbol index of the sear node in vertex // int32 sym_id = vertex->getItem()->getSymbolId(); v_d(i) = sym_id; } // output the debugging information // if (debug_level_d >= Integral::ALL) { String output(L"converted context: "); for (int32 i = length(); i > 0 ; i--) { output.concat((*this)(-i)); } Console::put(output); } // exit gracefully // return true; } // method: convert // // arguments: // Context*& output_a: (output) symbol indices of the graph vertices // bool8 extended_a: (input) flag that indicates and extended context // // return: a bool8 value indicating status // // this method converts pointers to graph vertices in this context to // search symbol indices (not reversible) // bool8 Context::convert(Context*& output_a, bool8 extended_a) { // determine the total context length // int32 total_length = length(); int32 context_length = total_length - ext_length_d; // initialize the output context // if (output_a != (Context*)NULL) { return Error::handle(name(), L"convert - output context is not null", Error::ARG, __FILE__, __LINE__); } output_a = new Context(context_length, central_d); // loop over all context symbols in current context, starting from // the oldest one // GVSnode* vertex = (GVSnode*)NULL; for (int32 i = total_length; i > ext_length_d; i--) { // get the i-th previous context symbol // if (extended_a) { vertex = (GVSnode*)(ulong)(*this)(-i + ext_length_d); } else { vertex = (GVSnode*)(ulong)(*this)(-i); } // check for the NULL vertex // if (vertex == (GVSnode*)NULL) { vertex = getCentralVertex()->getItem()->getSearchLevel()-> getSubGraph((int32)0).getTerm(); } // get the symbol index of the search node in vertex // ulong symbol_id = vertex->getItem()->getSymbolId(); output_a->assignAndAdvance(symbol_id); } // exit gracefully // return true; } // // arguments: none // // return: a bool8 value indicating status // // this methods shifts the extended context and reduces the size by one // bool8 Context::fold() { // declare local variables // Vector vec; int32 total_length = length(); // make sure the context has been extended // if (ext_length_d < 1) { return Error::handle(name(), L"fold", Error::ARG, __FILE__, __LINE__); } // rearrange items // vec.setLength(total_length - 1); for (int32 i = 1; i < total_length; i++) { vec(i - 1) = (*this)(i); } // reset the index and extension length // index_d = 0; ext_length_d--; // assign the new folded context // v_d.assign(vec); // exit gracefully // return true; } // method: extend // // arguments: // ulong pointer_to_vertex: (input) pointer to the vertex to be appended // // return: a bool8 value indicating status // // this method appends a pointer to graph vertex to the context // bool8 Context::extend(GVSnode* pointer_to_vertex_a) { // set the extension length, the extension length is zero in case we // have deep enough context // ext_length_d++; // if right context is extended deeper than right context length // then the buffer capacity have to be increased // if (ext_length_d > 0) { int32 new_length = length() + 1; v_d.setLength(new_length); // rearrange items // for (int32 i = new_length - 1; i > index_d; i--) { v_d(i) = v_d(i - 1); } } // append vertex // Ulong tmp = (ulong)pointer_to_vertex_a; assignAndAdvance(tmp); // exit gracefully // return true; }