LIMA
Libre Multilingual Analyzer — C++ API
Loading...
Searching...
No Matches
FsaAccessBuilder16.cpp
Go to the documentation of this file.
1// Copyright 2002-2013 CEA LIST
2// SPDX-FileCopyrightText: 2022 CEA LIST <gael.de-chalendar@cea.fr>
3//
4// SPDX-License-Identifier: MIT
5
6/***************************************************************************
7 * Copyright (C) 2003 by CEA *
8 * author Olivier MESNARD olivier.mesnard@cea.fr *
9 * *
10 * Compact dictionnary based on finite state automata implemented with *
11 * Boost Graph library. *
12 * Algorithm is described in article from Daciuk, Mihov, Watson & Watson: *
13 * "Incremental Construction of Minimal Acyclic Finite State Automata" *
14 ***************************************************************************/
15
16// for using hex and dec manipulators
17#include <iostream>
18
19// From boost library
20#include <boost/config.hpp>
21#include <boost/graph/adjacency_list.hpp>
22
23#include "common/LimaCommon.h"
24
25#include "FsaAccessBuilder16.h"
26#include "FsaAccessIOHandler.h"
27
28using namespace Lima;
29
30namespace Lima {
31namespace Common {
32namespace FsaAccess {
33
34
36: FsaAccess16<selected_graph_types16::builderGraphType>(trie_direction_fwd) ,
37 m_packingStatus(BUILDER)
38{
39}
40
44
48// return new FsaAccessIOHandlerWithoutMapping<selected_graph_types16::builderGraphType>();
49}
50
51// Same code as FsaAccessBuilderRandom !!
52// duplicated toi avoid multiple inheritance
53void FsaAccessBuilder16::write( const std::string & filename ){
54
55#ifdef DEBUG_CD
57 LDEBUG << "FsaAccessBuilder16::write(" << filename.c_str() << ")";
58#endif
59 std::ofstream os(filename.c_str(), std::ios::out | std::ios::binary );
60 if( !os.good() ) {
61 std::string mess = "FsaAccessBuilder16::write: Can't open file " + filename;
62#ifdef DEBUG_CD
63 LERROR;
64#endif
65 throw( FsaNotSaved( mess ) );
66 }
67// os.seekp(HEADER_SIZE ,std::ios_base::beg );
69 os.close();
70#ifdef DEBUG_CD
71 LDEBUG << "FsaAccessBuilder16::write(" << filename.c_str() << "): end";
72#endif
73}
74
75// Same code as FsaAccessBuilderRandom !!
76// duplicated toi avoid multiple inheritance
77void FsaAccessBuilder16::write ( std::ostream &os ){
78#ifdef DEBUG_CD
80 LDEBUG << "FsaAccessBuilder16::write(std::ostream)";
81#endif
82
85}
86
87// Same code as FsaAccessBuilderRandom !!
88// duplicated toi avoid multiple inheritance
90#ifdef DEBUG_CD
92 LDEBUG << "FsaAccessBuilder16::write(std::ostream)";
93#endif
94
97}
98
99// Same code as FsaAccessBuilderRandom !!
100// duplicated toi avoid multiple inheritance
102#ifdef DEBUG_CD
104 LDEBUG << "FsaAccessBuilder16::write()";
105#endif
106
107 FsaAccessHeader::setPackingStatus(m_packingStatus);
108
109 boost::graph_traits<graphType>::vertices_size_type nbVerts =
110 boost::num_vertices(m_graph);
111 boost::graph_traits<graphType>::edges_size_type nbEdges =
112 boost::num_edges(m_graph);
113
116
118
119 #ifdef DEBUG_CD
120 LDEBUG << "FsaAccessBuilder16::write: call to writeBody";
121#endif
122 writeBody( ow );
123 #ifdef DEBUG_CD
124 LDEBUG << "FsaAccessBuilder16::write: end";
125#endif
126}
127
129#ifdef DEBUG_CD
131 LDEBUG << "FsaAccessBuilder::pack()";
132#endif
133 if(m_packingStatus==BUILDER) {
135 m_packingStatus = BUILT;
136 }
137}
138
140#ifdef DEBUG_CD
142 LDEBUG << "FsaAccessBuilder::addWord(" << newWord << ")";
143#endif
144 dicoVertex prefix_leaf = m_rootVertex;
145
146 PrefixIterator* prefixIt = getPrefixIterator(newWord);
147 getPrefix( prefix_leaf, prefixIt );
148#ifdef DEBUG_CD
149 LWARN << "FsaAccessBuilder::addWord: prefix = " << prefixIt->getCurrentPrefix();
150#endif
151
152 if( !prefixIt->hasNextLetter() ) {
153#ifdef DEBUG_CD
154 LWARN << "FsaAccessBuilder::addWord: already in dictionary!!! ";
155#endif
156 return;
157 }
158
159 replaceOrRegister(prefix_leaf);
160 addSuffix( prefix_leaf, prefixIt );
161 delete prefixIt;
162}
163
164void FsaAccessBuilder16::replaceOrRegister( dicoVertex candidateState ) {
165#ifdef DEBUG_CD
167 LDEBUG << "FsaAccessBuilder::replaceOrRegister: (" << candidateState << ")";
168#endif
169
170 // check if leaf
171 // degree_size_type nbChild = out_degree(dicoVertex, m_graph);
172 // if( nbChild == 0)
173 dico_degree_size nbChild = boost::out_degree(candidateState, m_graph);
174 #ifdef DEBUG_CD
175 LDEBUG << "FsaAccessBuilder::replaceOrRegister: out_degree = " << nbChild;
176 #endif
177 if( nbChild == 0) {
178 return;
179 }
180
181 // get Last Child
182 boost::graph_traits<graphType>::out_edge_iterator ei, edge_end;
183 boost::tie(ei,edge_end) = boost::out_edges(candidateState,m_graph);
184
185// boost::graph_traits<graphType>::adjacency_iterator vi, v_end;
186// boost::tie(vi,v_end) = boost::adjacent_vertices(candidateState, m_graph);
187 //dicoVertex lastChild = *(v_end - 1);
188 for( dico_degree_size i = 0 ; i < nbChild - 1 ; i++ ) {
189 ei++;
190// vi++;
191 }
192 dicoVertex lastChild = boost::target(*ei, m_graph);
193
194 // recursive call
195 #ifdef DEBUG_CD
196 LDEBUG << "FsaAccessBuilder::replaceOrRegister: recursive call on" << lastChild;
197 #endif
198 replaceOrRegister( lastChild );
199
200 std::pair<const dicoVertex,bool> equivalent = findEquivalentInRegister( lastChild );
201 if( equivalent.second ) {
202 #ifdef DEBUG_CD
203 assert(equivalent.first != lastChild);
204 LDEBUG << "FsaAccessBuilder::replaceOrRegister: merging " << equivalent.first << " and " << lastChild << " with " << candidateState << " parent";
205 #endif
206 merge( equivalent.first, lastChild, candidateState );
207 }
208 else {
209 #ifdef DEBUG_CD
210 LDEBUG << "FsaAccessBuilder::replaceOrRegister: set HEAD_OF_CLASS_16 to " << lastChild;
211 #endif
212 dicoGraph_traits16<graphType>::nconst_vname_map_type vname_map = boost::get(boost::vertex_name,m_graph);
213 put(vname_map,lastChild, get(vname_map,lastChild)|HEAD_OF_CLASS_16);
214 }
215
216}
217
218void FsaAccessBuilder16::merge( dicoVertex inRegister,
219 dicoVertex tempState, dicoVertex parentState ) {
220#ifdef DEBUG_CD
222 LDEBUG << "FsaAccessBuilder16::merge( " << inRegister << ", "
223 << tempState << ", "
224 << parentState << ")";
225#endif
226 // find in transition parentState -> tempstate
227 std::pair<dicoEdgeType, bool> trans = edge(parentState, tempState, m_graph);
228#ifdef DEBUG_CD
229 Q_ASSERT( trans.second );
230#endif
231 // forward this transition to inRegister
232 if( trans.second ) {
233#ifdef DEBUG_CD
234 LDEBUG << "FsaAccessBuilder16::merge: add_edge(" << parentState << ", " << inRegister << ", " << ")";
235 #endif
236
237 std::pair<dicoEdgeType, bool> res = add_edge(parentState, inRegister, m_graph);
238 if (!res.second)
239 {
241 LERROR << "FsaAccessBuilder16::merge failed to add edge to the graph";
242 }
243#ifdef DEBUG_CD
244 Q_ASSERT( res.second );
245#endif
246 }
247
248 // delete tempstate
249 #ifdef DEBUG_CD
250 LDEBUG << "FsaAccessBuilder16::merge: remove vertex" << tempState;
251 #endif
252 clear_vertex(tempState, m_graph);
253 remove_vertex(tempState, m_graph);
254}
255
256
257} // namespace FsaAccess
258} // namespace Commmon
259} // namespace Lima
#define LWARN
Definition LimaCommon.h:160
#define LDEBUG
Definition LimaCommon.h:157
#define LERROR
Definition LimaCommon.h:161
#define FSAALOGINIT
Definition LimaCommon.h:206
#define FSAAIOLOGINIT
Definition LimaCommon.h:205
virtual void addSuffix(dicoVertexType from, PrefixIterator *prefixIt)
void getPrefix(dicoVertexType &from, PrefixIterator *prefixIt) const
Recursively goes through the graph from from, following edges labelled by the prefix iterator chars.
bool equivalent(dicoVertexType referenceState, dicoVertexType candidateState) const
are both state equivalent? We assume that edges are ordered
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)
virtual void replaceOrRegister(dicoVertex candidateState)
FsaAccessBuilder16(bool trie_direction_fwd=true)
void merge(dicoVertex inRegister, dicoVertex tempState, dicoVertex parentState)
FsaAccessIOHandler< graphType > * getFsaAccessIOHandler() const override
For IO Factory of IO Handler: Handler depends on graphType: with mapping or not.
virtual void addWord(const Lima::LimaString &newWord)
void write(const std::string &filename)
void write(AbstractFsaAccessOStreamWrapper &ow)
void setPackingStatus(uint8_t packingStatus)
virtual bool hasNextLetter() const =0
virtual const LimaString getCurrentPrefix() const =0
NAUTITIA.
QString LimaString
Definition LimaString.h:33
boost::property_map< graphType, boost::vertex_name_t >::type nconst_vname_map_type