17#include <boost/config.hpp>
18#include <boost/graph/adjacency_list.hpp>
50 std::ofstream os(filename.data(), std::ios::out | std::ios::binary | std::ios::app );
52 std::string mess =
"FsaAccessBuilderRandom16::write: Can't open file " + filename;
69 LDEBUG <<
"FsaAccessBuilderRandom16::write(std::ostream)";
81 LDEBUG <<
"FsaAccessBuilderRandom16::write(std::ostream)";
93 LDEBUG <<
"FsaAccessBuilderRandom16::write()";
98 boost::graph_traits<graphType>::vertices_size_type nbVerts =
100 boost::graph_traits<graphType>::edges_size_type nbEdges =
114 LDEBUG <<
"FsaAccessBuilderRandom16::addRandomWord("
116 std::ostringstream stro1(std::ios::in | std::ios::out);
119 LWARN <<
"FsaAccessBuilderRandom16::addRandomWord("
120 << stro1.str().c_str();
129 boost::get(boost::vertex_name,
m_graph);
131 dicoVertex prefix_leaf;
135 std::pair<AccessSuperWordIterator, AccessSuperWordIterator> superwords =
getSuperWords(newWord );
136 if( superwords.first == superwords.second ) {
137 LWARN <<
"FsaAccessBuilderRandom16::addRandomWord: "
139 <<
" already in dictionary!!";
143 LDEBUG <<
"FsaAccessBuilderRandom16::addRandomWord: "
145 <<
" as prefix of existing word";
149 (superwords.first)++;
150 for( ; superwords.first != superwords.second ; (superwords.first)++ ) {
153 if( nextSuperword.length() <= superword.length() )
156 superword = nextSuperword;
159 LDEBUG <<
"FsaAccessBuilderRandom16::addRandomWord: superWord = "
164 scanAndCloneConfluentStates(
m_rootVertex, prefixItSuperWord, prefix_leaf );
170 LWARN <<
"FsaAccessBuilderRandom16::addRandomWord: put(vname_map,"
171 << root <<
"," << get(vname_map, root)
174 put(vname_map, root, get(vname_map, root)|
FINAL_16);
176 LWARN << get(vname_map, root) <<
")";
179 LWARN <<
"FsaAccessBuilderRandom16::addRandomWord: put(vname_map,"
180 << prefix_leaf <<
"," << get(vname_map, prefix_leaf)
183 put(vname_map, prefix_leaf, get(vname_map, prefix_leaf)|
FINAL_16);
185 LWARN << get(vname_map, prefix_leaf) <<
")";
190 delete prefixItSuperWord;
193 std::ostringstream stro (std::ios::in | std::ios::out);
196 LDEBUG <<
"FsaAccessBuilderRandom16::addRandomWord: updateHash("
197 << stro.str().c_str() <<
")";
208 LDEBUG <<
"FsaAccessBuilderRandom16::addRandomWord: add complete word to root ";
218 scanAndCloneConfluentStates(
m_rootVertex, prefixItClone, prefix_leaf );
223 LDEBUG <<
"FsaAccessBuilderRandom16::addRandomWord: addSuffix to " << prefix_leaf;
228 dicoVertex newState = add_vertex(
m_graph);
229 put(vname_map, newState, 0);
235 LDEBUG <<
"FsaAccessBuilderRandom16::addRandomWord: add first letter of suffix "
239 addEdge( prefix_leaf, newState, currentChar, prefixIt->
getCurrentContent(), wordOffset );
241 prefixIt->
next(wordOffset);
249 LDEBUG <<
"FsaAccessBuilderRandom16::addRandomWord: add end of suffix "
250 <<
" to " << newState;
252 addSuffix( newState, prefixItAdd);
283bool FsaAccessBuilderRandom16::scanAndCloneConfluentStates(
284 boost::graph_traits<graphType>::vertex_descriptor from,
286 boost::graph_traits<graphType>::vertex_descriptor& lastState ) {
289 LDEBUG <<
"FsaAccessBuilderRandom16::scanAndCloneConfluentStates("
295 boost::get(boost::vertex_name,
m_graph);
304 LDEBUG <<
"FsaAccessBuilderRandom16::scanAndCloneConfluentStates: currentChar="
305 << currentChar <<
")";
315 int32_t edgeOffset = 0;
316 int32_t textOffset = 0;
320 LDEBUG <<
"FsaAccessBuilderRandom16::scanAndCloneConfluentStates: text = " << text8.c_str();
322 int32_t highCharTextPos = get(vname_map,from)&
TEXT_POS_16;
323 if( wordOffset == 1 ) {
324 textOffset =
findEdge( currentChar, text, 0, highCharTextPos, wordOffset );
325 edgeOffset = textOffset;
328 textOffset =
findEdge( currentChar, text, highCharTextPos, text.length(), wordOffset );
329 edgeOffset = highCharTextPos + (textOffset - highCharTextPos)/2;
332 if( edgeOffset >= 0 ) {
333 boost::graph_traits<graphType>::out_edge_iterator ei, edge_end;
334 boost::tie(ei,edge_end) = boost::out_edges(from,
m_graph);
339 for(
int i = 0 ; i < edgeOffset ; i++ )
343 boost::graph_traits<graphType>::vertex_descriptor to = target(edge,
m_graph);
345 LDEBUG <<
"FsaAccessBuilderRandom16::scanAndCloneConfluentStates: match " << edgeOffset;
347 graphType::degree_size_type ind = boost::in_degree(to,
m_graph);
352 graphType::degree_size_type outd0 = boost::out_degree(from,
m_graph);
353 std::vector<int>& counts = get(vcount_map,from);
355 Q_ASSERT( (counts.size() + 1) == outd0 );
357 Q_ASSERT( (counts.size() + 2) == outd0 );
360 Q_ASSERT( counts.size() == 0 );
364 LDEBUG <<
"FsaAccessBuilderRandom16::scanAndCloneConfluentStates: before remove_edge("
365 << from <<
"," << to <<
"), outd=" << outd0;
366 std::ostringstream oss2;
367 oss2 <<
"FsaAccessBuilderRandom16::scanAndCloneConfluentStates: remove_edge("
368 << edge <<
"," << (int)currentChar <<
")";
369 LDEBUG << oss2.str().c_str();
372 graphType::degree_size_type outd = boost::out_degree(from,
m_graph);
374 LDEBUG <<
"FsaAccessBuilderRandom16::scanAndCloneConfluentStates: after remove_edge, outd="
377 Q_ASSERT( (outd+1) == outd0);
379 Q_ASSERT( (counts.size() +1) == outd);
381 Q_ASSERT( counts.size() == 0 );
384 LDEBUG <<
"FsaAccessBuilderRandom16::scanAndCloneConfluentStates: before erase text[to] ="
387 text.remove(textOffset, wordOffset);
388 Q_ASSERT(
static_cast<graphType::degree_size_type
>(text.size()) == outd);
390 LDEBUG <<
"FsaAccessBuilderRandom16::scanAndCloneConfluentStates: after erase text[to] ="
395 LDEBUG <<
"FsaAccessBuilderRandom16::scanAndCloneConfluentStates: read val[to] ="
400 if( wordOffset == 1 )
402 Q_ASSERT( hicharOff == outd);
404 LDEBUG <<
"FsaAccessBuilderRandom16::scanAndCloneConfluentStates: set val[to] :="
405 << ( (qualif&(~HEAD_OF_CLASS_16)) | hicharOff);
409 boost::graph_traits<graphType>::vertex_descriptor newState;
411 cloneConfluentStates(currentChar, wordOffset, to, prefixIt, from, newState);
414 LDEBUG <<
"FsaAccessBuilderRandom16::scanAndCloneConfluentStates: duplicate out edges of "
415 << to <<
" into " << newState;
417 lastState = newState;
421 prefixIt->
next(wordOffset);
428 LWARN <<
"FsaAccessBuilderRandom16::scanAndCloneConfluentStates: no match for ";
455bool FsaAccessBuilderRandom16::cloneConfluentStates(
456 char32_t currentChar,
458 boost::graph_traits<graphType>::vertex_descriptor& toOldPath,
459 PrefixIterator* prefixIt,
460 boost::graph_traits<graphType>::vertex_descriptor fromNewPath,
461 boost::graph_traits<graphType>::vertex_descriptor& toNewPath ) {
465 LDEBUG <<
"FsaAccessBuilderRandom16::cloneConfluentStates("
466 << toOldPath <<
"," << prefixIt->getCurrentPrefix()
468 <<
"," << fromNewPath <<
")";
473 boost::get(boost::vertex_name,
m_graph);
476 graphType::degree_size_type out_size = boost::out_degree(fromNewPath,
m_graph);
477 LDEBUG <<
"FsaAccessBuilderRandom16::cloneConfluentStates: degree_size_type("
478 << fromNewPath <<
")=" << out_size <<
")";
481 toNewPath = add_vertex(
m_graph);
486 addEdge(fromNewPath, toNewPath, currentChar, prefixIt->getCurrentContent(), wordOffset );
487 cloneVertex(toOldPath, toNewPath );
489 prefixIt->next(wordOffset);
492 if( !prefixIt->hasNextLetter() ) {
495 currentChar = prefixIt->getNextLetter(wordOffset);
498 int32_t edgeOffset = 0;
500 boost::graph_traits<graphType>::out_edge_iterator ei, edge_end;
501 boost::tie(ei,edge_end) = boost::out_edges(toOldPath,
m_graph);
503 int32_t highCharTextPos = get(vname_map,toOldPath)&
TEXT_POS_16;
504 if( wordOffset == 1 ) {
505 edgeOffset =
findEdge( currentChar, text, 0, highCharTextPos, wordOffset );
509 textOffset =
findEdge( currentChar, text, highCharTextPos, text.length(), wordOffset );
510 edgeOffset = highCharTextPos + (textOffset - highCharTextPos)/2;
513 if( edgeOffset >= 0 ) {
514 boost::graph_traits<graphType>::out_edge_iterator ei, edge_end;
515 boost::tie(ei,edge_end) = boost::out_edges(toOldPath,
m_graph);
519 LDEBUG <<
"FsaAccessBuilderRandom16::cloneConfluentStates: match " << edgeOffset;
521 dicoVertex oldTarget = target(edge,
m_graph);
523 suppressEdge(toNewPath, oldTarget, currentChar, prefixIt->getCurrentContent(), wordOffset);
524 toOldPath = oldTarget;
526 bool ret = cloneConfluentStates( currentChar, wordOffset, toOldPath,
527 prefixIt, toNewPath, toNewPath);
532 LERROR <<
"FsaAccessBuilderRandom16::cloneConfluentStates: no match for"
540void FsaAccessBuilderRandom16::cloneVertex(
541 const boost::graph_traits<graphType>::vertex_descriptor oldTo,
542 const boost::graph_traits<graphType>::vertex_descriptor newTo )
546 LDEBUG <<
"FsaAccessBuilderRandom16::cloneVertex("
547 << oldTo <<
", " << newTo <<
")";
552 boost::get(boost::vertex_name,
m_graph);
556 boost::graph_traits<graphType>::out_edge_iterator ei, edge_end;
557 boost::tie(ei,edge_end) = boost::out_edges(oldTo,
m_graph);
558 graphType::degree_size_type outd0 = boost::out_degree(newTo,
m_graph);
559 graphType::degree_size_type outdRef = boost::out_degree(oldTo,
m_graph);
560 Q_ASSERT(outd0 == 0);
561 for( ; ei != edge_end ; ei++ ) {
562 dicoVertex currentTarget = target(*ei,
m_graph);
564 LDEBUG <<
"FsaAccessBuilderRandom16::cloneVertex: add_edge("
565 << newTo <<
"," << currentTarget <<
")";
567 add_edge(newTo, currentTarget,
m_graph );
569 graphType::degree_size_type outd = boost::out_degree(newTo,
m_graph);
570 Q_ASSERT( outd == outdRef );
572 std::vector<int>& counts = get(vcount_map,oldTo);
573 put(vcount_map,newTo,counts);
574 put(vtext_map,newTo,get(vtext_map,oldTo));
576 std::vector<int>& newCounts = get(vcount_map,newTo);
578 Q_ASSERT( (newCounts.size()+1) == outd );
580 Q_ASSERT( newCounts.size() == 0 );
583 Q_ASSERT(
static_cast<graphType::degree_size_type
>(text.size()) == outd );
588 put(vname_map,newTo,vval);
589 Q_ASSERT( (get(vname_map, newTo)&
TEXT_POS_16) == outd );
597void FsaAccessBuilderRandom16::addEdge(
598 const boost::graph_traits<graphType>::vertex_descriptor from,
599 const boost::graph_traits<graphType>::vertex_descriptor to,
600 const char32_t currentChar,
602 const int32_t wordOffset ) {
606 LDEBUG <<
"FsaAccessBuilderRandom16::addEdge("
607 << from <<
", " << to <<
", " << currentChar <<
","
608 <<
LimaString(*word_content) <<
", " << wordOffset <<
")";
613 boost::get(boost::vertex_name,
m_graph);
622 LDEBUG <<
"FsaAccessBuilderRandom16::addEdge: vval="
624 <<
", highCharTextPos=" << highCharTextPos ;
628 std::vector<int>& counts = get(vcount_map,from);
629 graphType::degree_size_type outd0 = boost::out_degree(from,
m_graph);
632 if( wordOffset == 1 ) {
633 if( highCharTextPos > 0 )
639 std::list<dicoVertex> newOrderedTargetList;
643 boost::graph_traits<graphType>::out_edge_iterator ei, edge_end;
644 boost::tie(ei,edge_end) = boost::out_edges(from,
m_graph);
645 int32_t textOffset(0);
647 for( ; ei != edge_end ; ei++ ) {
648 if( textOffset == textOffset0 )
654 newOrderedTargetList.push_back(target(*ei,
m_graph));
659 newOrderedTargetList.push_back(to);
661 for( ; ei != edge_end ; ei++ ) {
666 newOrderedTargetList.push_back(target(*ei,
m_graph));
670 LDEBUG <<
"FsaAccessBuilderRandom16::addEdge: clear_edge("
671 << from <<
")" <<
"(" << newOrderedTargetList.size() <<
")";
673 clear_out_edges(from,
m_graph);
674 Q_ASSERT(boost::out_degree(from,
m_graph) == 0);
676 for( std::list<dicoVertex>::const_iterator vIt = newOrderedTargetList.begin() ;
677 vIt != newOrderedTargetList.end() ; vIt++ ) {
679 LDEBUG <<
"FsaAccessBuilderRandom16::addEdge: add_edge("
680 << from <<
"," << *vIt <<
"";
682 add_edge(from, *vIt,
m_graph );
684 graphType::degree_size_type outd = boost::out_degree(from,
m_graph);
685 Q_ASSERT(outd == newOrderedTargetList.size() );
686 Q_ASSERT(outd == (outd0+1) );
691 LDEBUG <<
"FsaAccessBuilderRandom16::addEdge: counts.push_back(0)";
698 LDEBUG <<
"FsaAccessBuilderRandom16::addEdge: outd=" << outd
699 <<
", highCharTextPos = " << highCharTextPos;
701 Q_ASSERT(outd == highCharTextPos );
704 qualif = qualif & (~HEAD_OF_CLASS_16);
706 LDEBUG <<
"FsaAccessBuilderRandom16::addEdge: put(vname_map,"
707 << from <<
"," << qualif
708 <<
" | " << highCharTextPos <<
"" ;
710 put(vname_map, from, qualif | highCharTextPos);
712 LDEBUG <<
"FsaAccessBuilderRandom16::addEdge: text("
716 LDEBUG <<
"FsaAccessBuilderRandom16::addEdge: text="
720 LDEBUG <<
"FsaAccessBuilderRandom16::addEdge: text.insert("
721 << textOffset0 <<
","
724 text.insert(textOffset0, word_content, wordOffset);
726 LDEBUG <<
"FsaAccessBuilderRandom16::addEdge: text("
730 LDEBUG <<
"FsaAccessBuilderRandom16::addEdge: text="
736 LDEBUG <<
"FsaAccessBuilderRandom16::addEdge: findOffsetToInsertBefore("
737 << currentChar <<
","
746 graphType::degree_size_type outdCheck = boost::out_degree(from,
m_graph);
748 Q_ASSERT( (counts.size()+1) == outdCheck );
750 Q_ASSERT( counts.size() == 0 );
751 Q_ASSERT( (get(vname_map, from)&
TEXT_POS_16) == outdCheck );
753 Q_ASSERT(
static_cast<graphType::degree_size_type
>(textCheck.size()) == outdCheck );
763void FsaAccessBuilderRandom16::replaceEdge(
764 const boost::graph_traits<graphType>::vertex_descriptor from,
765 const boost::graph_traits<graphType>::vertex_descriptor to,
766 const char32_t currentChar,
767 const int32_t wordOffset ) {
771 LDEBUG <<
"FsaAccessBuilderRandom16::replaceEdge("
772 << from <<
", " << to <<
", " << currentChar <<
","
773 <<
", " << wordOffset <<
")";
780 boost::get(boost::vertex_name,
m_graph);
788 graphType::degree_size_type outd0 = boost::out_degree(from,
m_graph);
789 uint32_t textOffset0;
790 if( wordOffset == 1 ) {
791 if( highCharTextPos > 0 )
797 LDEBUG <<
"FsaAccessBuilderRandom16::replaceEdge: textOffset0="
802 std::list<dicoVertex> newOrderedTargetList;
806 boost::graph_traits<graphType>::out_edge_iterator ei, edge_end;
807 boost::tie(ei,edge_end) = boost::out_edges(from,
m_graph);
808 uint32_t textOffset(0);
810 for( ; ei != edge_end ; ei++ ) {
811 if( textOffset == textOffset0 ) {
819 newOrderedTargetList.push_back(target(*ei,
m_graph));
822 newOrderedTargetList.push_back(to);
823 Q_ASSERT(newOrderedTargetList.size() == textOffset+1);
826 for( ; ei != edge_end ; ei++ ) {
831 newOrderedTargetList.push_back(target(*ei,
m_graph));
833 Q_ASSERT(newOrderedTargetList.size() == outd0);
836 LDEBUG <<
"FsaAccessBuilderRandom16::replaceEdge: clear_edge("
839 clear_out_edges(from,
m_graph);
840 Q_ASSERT(boost::out_degree(from,
m_graph) == 0);
842 for( std::list<dicoVertex>::iterator vIt = newOrderedTargetList.begin() ;
843 vIt != newOrderedTargetList.end() ; vIt++ ) {
845 LDEBUG <<
"FsaAccessBuilderRandom16::replaceEdge: add_edge("
846 << from <<
"," << *vIt <<
"";
848 add_edge(from, *vIt,
m_graph );
850 Q_ASSERT(boost::out_degree(from,
m_graph) == outd0);
853 qualif = qualif & (~HEAD_OF_CLASS_16);
855 LDEBUG <<
"FsaAccessBuilderRandom16::replaceEdge: put(vname_map,"
856 << from <<
"," << qualif <<
" | " << highCharTextPos <<
"";
858 put(vname_map, from, qualif | highCharTextPos);
862 LDEBUG <<
"FsaAccessBuilderRandom16::replaceEdge: findOffsetToInsertBefore("
864 << currentChar <<
"," <<
")";
872 Q_ASSERT( (get(vname_map, from)&
TEXT_POS_16) == outd0 );
873 std::vector<int>& counts = get(vcount_map,from);
875 Q_ASSERT( (counts.size()+1) == outd0 );
877 Q_ASSERT( counts.size() == 0 );
879 Q_ASSERT(
static_cast<graphType::degree_size_type
>(textCheck.size()) == outd0 );
884void FsaAccessBuilderRandom16::suppressEdge(
885 const boost::graph_traits<graphType>::vertex_descriptor from,
886 const boost::graph_traits<graphType>::vertex_descriptor to,
887 const char32_t currentChar,
889 const int32_t wordOffset ) {
893 LDEBUG <<
"FsaAccessBuilderRandom16::suppressEdge("
894 << from <<
", " << to <<
", " << currentChar <<
","
895 <<
LimaString(*word_content) <<
", " << wordOffset <<
")";
903 boost::get(boost::vertex_name,
m_graph);
913 std::vector<int>& counts = get(vcount_map,from);
914 graphType::degree_size_type outd0 = boost::out_degree(from,
m_graph);
915 Q_ASSERT( outd0 > 0 );
917 Q_ASSERT( (counts.size()+1) == outd0 );
919 Q_ASSERT( counts.size() == 0 );
922 if( wordOffset == 1 ) {
923 if( highCharTextPos > 0 ) {
930 std::list<dicoVertex> newOrderedTargetList;
934 boost::graph_traits<graphType>::out_edge_iterator ei, edge_end;
935 boost::tie(ei,edge_end) = boost::out_edges(from,
m_graph);
936 int32_t textOffset(0);
938 std::vector<int>::iterator cIt = counts.begin();
939 for( ; ei != edge_end ; ei++, cIt++ ) {
940 if( textOffset == textOffset0 )
946 newOrderedTargetList.push_back(target(*ei,
m_graph));
958 for( ; ei != edge_end ; ei++ ) {
963 newOrderedTargetList.push_back(target(*ei,
m_graph));
967 LDEBUG <<
"FsaAccessBuilderRandom16::suppressEdge: clear_edge("
970 clear_out_edges(from,
m_graph);
971 Q_ASSERT(boost::out_degree(from,
m_graph) == 0);
973 for( std::list<dicoVertex>::iterator vIt = newOrderedTargetList.begin() ;
974 vIt != newOrderedTargetList.end() ; vIt++ ) {
976 LDEBUG <<
"FsaAccessBuilderRandom16::suppressEdge: add_edge("
977 << from <<
"," << *vIt <<
"";
979 add_edge(from, *vIt,
m_graph );
983 qualif = qualif & (~HEAD_OF_CLASS_16);
985 LDEBUG <<
"FsaAccessBuilderRandom16::suppressEdge: put(vname_map,"
986 << from <<
"," << qualif <<
" | " << highCharTextPos <<
"";
988 put(vname_map, from, qualif | highCharTextPos);
990 LDEBUG <<
"FsaAccessBuilderRandom16::suppressEdge: text("
993 LDEBUG <<
"FsaAccessBuilderRandom16::suppressEdge: text="
997 LDEBUG <<
"FsaAccessBuilderRandom16::suppressEdge: text.erase("
999 << textOffset0 <<
"," <<
")";
1001 text.remove(textOffset0, wordOffset);
1003 LDEBUG <<
"FsaAccessBuilderRandom16::suppressEdge: text("
1006 LDEBUG <<
"FsaAccessBuilderRandom16::suppressEdge: text="
1013 LDEBUG <<
"FsaAccessBuilderRandom16::suppressEdge: findOffsetToInsertBefore("
1015 << currentChar <<
"," <<
")";
1023 graphType::degree_size_type outd = boost::out_degree(from,
m_graph);
1024 Q_ASSERT((outd+1) == outd0);
1025 Q_ASSERT( (get(vname_map, from)&
TEXT_POS_16) == outd );
1027 Q_ASSERT( (counts.size()+1) == outd );
1029 Q_ASSERT( counts.size() == 0 );
1031 Q_ASSERT(
static_cast<graphType::degree_size_type
>(textCheck.size()) == outd );
1035void FsaAccessBuilderRandom16::replaceOrRegister( dicoVertex candidateState,
1036 PrefixIterator* prefixIt ){
1040 LDEBUG <<
"FsaAccessBuilderRandom16::replaceOrRegister: (" << candidateState <<
")";
1046 dico_degree_size nbChild = boost::out_degree(candidateState,
m_graph);
1047 if( nbChild == 0 ) {
1049 LDEBUG <<
"FsaAccessBuilderRandom16::replaceOrRegister: out_degree = 0";
1056 Q_ASSERT( prefixIt->hasNextLetter() );
1057 char32_t currentChar = prefixIt->getNextLetter(wordOffset);
1060 LDEBUG <<
"FsaAccessBuilderRandom16::replaceOrRegister: currentChar="
1061 << currentChar <<
")";
1067 boost::get(boost::vertex_name,
m_graph);
1069 int32_t edgeOffset = 0;
1070 int32_t textOffset = 0;
1073 std::string text8 =
LimaString(text.data()).toStdString();
1074 LDEBUG <<
"FsaAccessBuilderRandom16::replaceOrRegister: text = " << text8.c_str();
1076 int32_t highCharTextPos = get(vname_map,candidateState)&
TEXT_POS_16;
1077 if( wordOffset == 1 ) {
1078 textOffset =
findEdge( currentChar, text, 0, highCharTextPos, wordOffset );
1079 edgeOffset = textOffset;
1082 textOffset =
findEdge( currentChar, text, highCharTextPos, text.length(), wordOffset );
1083 edgeOffset = highCharTextPos + (textOffset - highCharTextPos)/2;
1086 if( edgeOffset >= 0 ) {
1087 prefixIt->next(wordOffset);
1088 boost::graph_traits<graphType>::out_edge_iterator ei, edge_end;
1089 boost::tie(ei,edge_end) = boost::out_edges(candidateState,
m_graph);
1091 boost::graph_traits<graphType>::vertex_descriptor lastChild = target(edge,
m_graph);
1094 replaceOrRegister( lastChild, prefixIt );
1098 ForwardPrefixIterator textIt( text, textOffset );
1099 merge(
equivalent.first, lastChild, candidateState, textIt );
1103 LDEBUG <<
"FsaAccessBuilderRandom16::replaceOrRegister: m_register.push_back("
1104 << lastChild <<
")";
1107 boost::get(boost::vertex_name,
m_graph);
1112 std::string mess(
"FsaAccessBuilderRandom16::replaceOrRegister: no path to reach 0degreeVertex!!");
1121void FsaAccessBuilderRandom16::merge( dicoVertex inRegister,
1122 dicoVertex tempState, dicoVertex parentState,
1123 const ForwardPrefixIterator& textIt) {
1126 LDEBUG <<
"FsaAccessBuilderRandom16::merge( " << inRegister <<
", "
1127 << tempState <<
", "
1128 << parentState <<
")";
1131 std::pair<dicoEdgeType, bool> trans = edge(parentState, tempState,
m_graph);
1132 Q_ASSERT( trans.second );
1134 if( trans.second ) {
1136 LDEBUG <<
"FsaAccessBuilderRandom16::merge: replaceEdge(" << parentState <<
", "
1137 << inRegister <<
", "
1142 char32_t currentChar = textIt.getNextLetter(wordOffset);
1143 replaceEdge( parentState, inRegister, currentChar, wordOffset );
1150 clear_vertex(tempState,
m_graph);
1151 remove_vertex(tempState,
m_graph);
1156int FsaAccessBuilderRandom16::updateHash( dicoVertex from,
1157 PrefixIterator* prefixIt ) {
1161 std::ostringstream stro1(std::ios::in | std::ios::out);
1162 stro1 << from <<
"(nbChild=" << boost::out_degree(from,
m_graph) <<
"), " << *prefixIt;
1163 LDEBUG <<
"FsaAccessBuilderRandom16::updateHash("
1164 << stro1.str().c_str() <<
")";
1168 boost::get(boost::vertex_name,
m_graph);
1177 std::vector<int>& counts = get(vcount_map,from);
1183 dico_degree_size nbChild = boost::out_degree(from,
m_graph);
1184 if( nbChild == 0 ) {
1186 LDEBUG <<
"FsaAccessBuilderRandom16::updateHash: out_degree = 0";
1191 LDEBUG <<
"FsaAccessBuilderRandom16::updateHash: FINAL node, increment " << total ;
1199 Q_ASSERT(nbChild == (counts.size()+1) );
1201 Q_ASSERT( counts.size() == 0 );
1207 int32_t edgeOffset = 0;
1208 int32_t textOffset = 0;
1209 if( prefixIt->hasNextLetter() ) {
1210 char32_t currentChar = prefixIt->getNextLetter((int32_t&)wordOffset);
1212 LDEBUG <<
"FsaAccessBuilderRandom16::updateHash: currentChar="
1213 << currentChar <<
")";
1219 LDEBUG <<
"FsaAccessBuilderRandom16::updateHash: text = " << text8.c_str();
1222 if( wordOffset == 1 ) {
1223 textOffset =
findEdge( currentChar, text, 0, highCharTextPos, wordOffset );
1224 edgeOffset = textOffset;
1227 textOffset =
findEdge( currentChar, text, highCharTextPos, text.length(), wordOffset );
1228 edgeOffset = highCharTextPos + (textOffset - highCharTextPos)/2;
1230 prefixIt->next(wordOffset);
1237 if( edgeOffset >= 0 ) {
1238 boost::graph_traits<graphType>::out_edge_iterator ei, edge_end;
1239 boost::tie(ei,edge_end) = boost::out_edges(from,
m_graph);
1241 boost::graph_traits<graphType>::vertex_descriptor lastChild = target(edge,
m_graph);
1243 int subtotal = updateHash( lastChild, prefixIt );
1246 graphType::degree_size_type outd = boost::out_degree(from,
m_graph);
1248 std::vector<int>::iterator cIt = counts.begin();
1250 LDEBUG <<
"FsaAccessBuilderRandom16::updateHash: counts.size()="
1254 for( ; (i+1 <
static_cast<int32_t
>(outd)) && (i<edgeOffset) ; ei++ , i++, cIt++ ) {
1255 Q_ASSERT(ei != edge_end);
1256 total = total + *cIt;
1260 if( i+1 <
static_cast<int32_t
>(outd) ){
1262 LDEBUG <<
"FsaAccessBuilderRandom16::updateHash: i="
1263 << i <<
",total=" << total <<
", subtotal=" << subtotal;
1265 delta = (total + subtotal) - *cIt;
1266 *cIt = total + subtotal;
1272 for( ; i+1 <
static_cast<int32_t
>(outd) ; ei++ , i++, cIt++ ) {
1274 LDEBUG <<
"FsaAccessBuilderRandom16::updateHash: i="
1275 << i <<
",*cIt=" << *cIt <<
", delta=" << delta;
1277 Q_ASSERT(ei != edge_end);
1278 total = *cIt + delta;
1283 if( ei != edge_end ) {
1289 total = total + subtotal;
1291 put(vname_map, from, get(vname_map, from) |
SET_16);
1295 LDEBUG <<
"FsaAccessBuilderRandom16::updateHash: FINAL node, increment " << total ;
1300 LDEBUG <<
"FsaAccessBuilderRandom16::updateHash: return " << total ;
1305 std::string mess(
"FsaAccessBuilderRandom16::updateHash: no path to reach 0degreeVertex!!");
1313void FsaAccessBuilderRandom16::addSuffix( dicoVertex from, PrefixIterator* prefixIt ) {
1317 LDEBUG <<
"FsaAccessBuilderRandom16::addSuffix: (" << from
1318 <<
", " << s <<
")";
1322 boost::get(boost::vertex_name,
m_graph);
1324 int32_t prefixOffset;
1325 dicoVertex to = from;
1326 for( ; prefixIt->hasNextLetter() ; prefixIt->next(prefixOffset) ) {
1329 put(vname_map, to, 0);
1331 char32_t letter = prefixIt->getNextLetter(prefixOffset);
1334 sprintf(buff,
"letter = %04x, suffixPos=%d\n", letter, prefixIt->getExternalWordPos() );
1339 LDEBUG <<
"FsaAccessBuilderRandom16::addSuffix: add_edge(" << from
1340 <<
", " << to <<
")";
1343 addEdge( from, to, letter, prefixIt->getCurrentContent(), prefixOffset );
1347 LDEBUG <<
"FsaAccessBuilderRandom16::addSuffix: put(vname_map, to="
Use this exception to signal the used of a wrongly initialized LIMA dictionary.
void getPrefix(dicoVertexType &from, PrefixIterator *prefixIt) const
Recursively goes through the graph from from, following edges labelled by the prefix iterator chars.
dicoVertexType m_rootVertex
int32_t findEdge(const char32_t searchChar, const LimaString &textString, int32_t min, int range, int nb_unit_for_char) const
find the right offset in the vector of out_edge: search for the character currentChar in the string t...
bool equivalent(dicoVertexType referenceState, dicoVertexType candidateState) const
are both state equivalent? We assume that edges are ordered
void writeBody(AbstractFsaAccessOStreamWrapper &ow)
std::pair< const dicoVertexType, bool > findEquivalentInRegister(dicoVertexType tempState)
Search for equivalent state in register.
PrefixIterator * getPrefixIterator(const LimaString &word, const uint64_t offset=0) const
For all navigation Factory of prefixIterator (prefixIt depends on direction: forward/reverse)
boost::graph_traits< graphType >::edge_descriptor dicoEdgeType
type of vertex descriptor type of edge descriptor
int32_t findOffsetToInsertBefore(const char32_t searchChar, const LimaString &textString, int32_t min, int range, int nb_unit_per_char) const
find where to insert currentChar in the string text using dichotomy search (assume characters are ord...
FsaAccessIOHandler< graphType > * getFsaAccessIOHandler() const override
For IO Factory of IO Handler: Handler depends on graphType: with mapping or not.
void write(const std::string &filename)
void addRandomWord(const Lima::LimaString &newWord) override
gives the number of entries
virtual ~FsaAccessBuilderRandom16()
FsaAccessBuilderRandom16(bool trie_direction_fwd=true)
virtual std::pair< AccessSuperWordIterator, AccessSuperWordIterator > getSuperWords(const LimaString &word) const override
int computeHash(typename boost::graph_traits< selected_graph_types16::builderGraphType >::vertex_descriptor from)
virtual void next(const int32_t wordOffset)=0
virtual const Lima::LimaChar * getCurrentContent() const =0
virtual bool hasNextLetter() const =0
int32_t getWordPos() const
virtual char32_t getNextLetter(int32_t &wordOffset) const =0
virtual const LimaString getPastPrefix() const =0
virtual const LimaString getCurrentPrefix() const =0
std::string limastring2utf8stdstring(const Lima::LimaString &phrase, uint32_t size0)
Convert a wide string to a string , in dest up to size bytes.
boost::property_map< graphType, vertex_count_t >::type nconst_vcount_map_type
boost::property_map< graphType, vertex_text_t >::type nconst_vtext_map_type
boost::property_map< graphType, boost::vertex_name_t >::type nconst_vname_map_type