LIMA
Libre Multilingual Analyzer — C++ API
Loading...
Searching...
No Matches
SyntacticAnalyzer-hetero.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
25#include "SimplificationData.h"
26
27#define SAHLOGINIT LOGINIT("LP::SyntacticAnalysis::Hetero")
28
29using namespace std;
30using namespace Lima::Common::MediaticData;
33
34namespace Lima {
35namespace LinguisticProcessing {
36namespace SyntacticAnalysis {
37
40
41//***********************************************************************
42// constructors
43//***********************************************************************
45m_language(),
46m_recognizer(0),
47m_unfold(true),
48m_linkSubSentences(true),
49m_applySameRuleWhileSuccess(false)
50{
51}
52
55m_language(s.m_language),
56m_recognizer(s.m_recognizer),
57m_unfold(s.m_unfold),
58m_linkSubSentences(s.m_linkSubSentences),
59m_applySameRuleWhileSuccess(s.m_applySameRuleWhileSuccess)
60{
61}
62
63//***********************************************************************
64// destructor
65//***********************************************************************
69
70//***********************************************************************
71// assignment operator
72//***********************************************************************
81
82//***********************************************************************
83// initialization
84//***********************************************************************
86 Manager* manager)
87
88{
90 try {
91 std::string rules=unitConfiguration.getParamsValueAtKey("rules");
92 m_recognizer = std::dynamic_pointer_cast<Automaton::Recognizer>(LinguisticResources::single().getResource(m_language,rules));
93 }
95 {
97 LERROR << "no parameter 'rules' in SyntacticAnalyzerDepsHetero group for language "
98 << (int) m_language;
99 }
100 try {
101 std::map<std::string,std::string>& rulesMap=unitConfiguration.getMapAtKey("subSentencesRules");
102 std::map<std::string,std::string>::const_iterator itm, itm_end;
103 itm = rulesMap.begin(); itm_end = rulesMap.end();
104 for (; itm != itm_end; itm++)
105 {
107 LINFO << "Loading subsentences recognizer " << (*itm).second << " for type " << (*itm).first;
109 std::make_pair(
110 static_cast<const Common::MediaticData::LanguageData&>(Common::MediaticData::MediaticData::single().mediaData(m_language)).getSyntacticRelationId((*itm).first),
111 std::dynamic_pointer_cast<Automaton::Recognizer>(LinguisticResources::single().getResource(m_language,(*itm).second))));
112 }
113 }
115 {
117 LERROR << "no parameters map 'subSentencesRules' in SyntacticAnalyzerDepsHetero group for language "
118 << (int) m_language;
119 }
120
121 try
122 {
123 std::string unfold=unitConfiguration.getParamsValueAtKey("unfold");
124 if (unfold == "true") m_unfold = true;
125 else m_unfold = false;
126 }
128 {
130 LINFO << "no parameter 'unfold' in SyntacticAnalyzerDepsHetero group for language "
131 << (int) m_language << " ; using default : true";
132 }
133 if (m_unfold)
134 {
135 try {
136 std::string linkSubSentences=unitConfiguration.getParamsValueAtKey("linkSubSentences");
137 if (linkSubSentences == "true") m_linkSubSentences = true;
138 else m_linkSubSentences = false;
139 }
141 {
143 LINFO << "no parameter 'linkSubSentences' in SyntacticAnalyzerDepsHetero group for language "
144 << (int) m_language << " ; using default : true";
145 }
146 }
147
148 try {
149 std::string val=unitConfiguration.getParamsValueAtKey("applySameRuleWhileSuccess");
150 if (val == "true" || val == "yes") {
152 }
153 else {
155 }
156 }
157 catch (Common::XMLConfigurationFiles::NoSuchParam& ) {} // keep default value
158}
159
160//***********************************************************************
161// main process function
162//***********************************************************************
164{
165 Lima::TimeUtilsController timer("SyntacticAnalysis");
167 LINFO << "start heterosyntagmatic dependence relations search";
168
169 auto posgraph = std::dynamic_pointer_cast<AnalysisGraph>(analysis.getData("PosGraph"));
170 if (posgraph==0)
171 {
172 LERROR << "no AnalysisGraph ! abort";
173 return MISSING_DATA;
174 }
175 LinguisticGraph* graph = posgraph->getGraph();
176
177 auto sb = std::dynamic_pointer_cast<SegmentationData>(analysis.getData("SentenceBoundaries"));
178 if (sb==0)
179 {
180 LERROR << "no sentence bounds ! abort";
181 return MISSING_DATA;
182 }
183 if (sb->getGraphId() != "PosGraph") {
184 LERROR << "SentenceBounds have been computed on " << sb->getGraphId() << " !";
185 LERROR << "SyntacticAnalyzer-deps needs SentenceBounds on PosGraph";
187 }
188
189 auto simplificationData = std::dynamic_pointer_cast<SimplificationData>(analysis.getData("SimplificationData"));
190 if (simplificationData==0)
191 {
192 simplificationData = std::make_shared<SimplificationData>(posgraph.get());
193 analysis.setData("SimplificationData",simplificationData);
194 }
195
196
197 // ??OME2 for (SegmentationData::const_iterator boundItr=sb->begin();
198 // boundItr!=sb->end();
199 for (std::vector<Segment>::const_iterator boundItr=(sb->getSegments()).begin();
200 boundItr!=(sb->getSegments()).end();
201 boundItr++)
202 {
203 LinguisticGraphVertex beginSentence=boundItr->getFirstVertex();
204 LinguisticGraphVertex endSentence=boundItr->getLastVertex();
205#ifdef DEBUG_LP
206 LDEBUG << "analyze sentence from vertex " << beginSentence
207 << " to vertex " << endSentence;
208#endif
209
210 std::vector<Automaton::RecognizerMatch> result;
211 m_recognizer->apply(*posgraph,
212 beginSentence,
213 endSentence,
214 analysis,
215 result,
216 true, // test all vertices=true
217 false, // stop at first success=false
218 false, // only one success per type=true
219 false, // return at first success=false
220 m_applySameRuleWhileSuccess // depends on config file
221 );
222
231 auto subSentRIt = simplificationData->simplifications(beginSentence).rbegin();
232 auto subSentRIt_end = simplificationData->simplifications(beginSentence).rend();
233 for (; subSentRIt != subSentRIt_end; subSentRIt++)
234 {
238 boost::tie(first, last, subSentType) = *subSentRIt;
239 std::vector<Automaton::RecognizerMatch> subSentResult;
240#ifdef DEBUG_LP
241 LDEBUG << "Hetero rules on a subsentence: " << boost::target(first,*graph) << " / " << boost::source(last,*graph);
242#endif
243
244 m_recognizer->apply(*posgraph,
245 boost::target(first,*graph),
246 boost::source(last,*graph),
247 analysis,
248 subSentResult,
249 true, // test all vertices=true
250 false, // stop at first success=false
251 true, // only one success per type=true
252 false, // return at first success=false
253 false //applySameRuleWhileSuccess=false
254 );
255 if (m_unfold)
256 {
257#ifdef DEBUG_LP
258 LDEBUG << "Unfolding";
259 LDEBUG << "Remove edge " << boost::source(first,*graph) << " -> " << boost::target(last,*graph);
260#endif
261 boost::remove_edge(boost::source(first,*graph),
262 boost::target(last,*graph),
263 *graph);
264 if (!boost::edge(boost::source(first,*graph),
265 boost::target(first,*graph),
266 *graph).second)
267 {
268#ifdef DEBUG_LP
269 LDEBUG << "Add edge " << boost::source(first,*graph) << " -> " << boost::target(first,*graph);
270#endif
271 boost::add_edge(boost::source(first,*graph),
272 boost::target(first,*graph),
273 *graph);
274 }
275 if (!boost::edge(boost::source(last,*graph),
276 boost::target(last,*graph),
277 *graph).second)
278 {
279#ifdef DEBUG_LP
280 LDEBUG << "Add edge " << boost::source(last,*graph) << " -> " << boost::target(last,*graph);
281#endif
282 boost::add_edge(boost::source(last,*graph),
283 boost::target(last,*graph),
284 *graph);
285 }
287 {
288 if (m_subSentRecognizers.find(subSentType) == m_subSentRecognizers.end())
289 {
290 LWARN << "No recognizer for subsentence type " << subSentType;
291 }
292 else
293 {
294#ifdef DEBUG_LP
295 LDEBUG << "Link subsentence to main one " << boost::target(first,*graph) << "/"
296 << boost::source(last,*graph) << "/" << beginSentence << "/"
297 << endSentence;
298#endif
299 auto subSentRecognizer = (*(m_subSentRecognizers.find(subSentType))).second;
300 subSentRecognizer->apply(*posgraph,
301 boost::target(first,*graph),
302 boost::source(last,*graph),
303 beginSentence,
304 endSentence,
305 analysis,
306 subSentResult,
307 true, // test all vertices=true
308 true, // stop at first success=false
309 true, // only one success per type=true
310 true, // return at first success=true
311 false //applySameRuleWhileSuccess=false
312 );
313 }
314 }
315 }
316 }
319 recopyCoordinationStrings(analysis);
320 }
321 return SUCCESS_ID;
322}
323
324LimaStatusCode SyntacticAnalyzerDepsHetero::recopyCoordinationStrings(AnalysisContent& analysis) const
325{
326#ifdef DEBUG_LP
328 LDEBUG << "SyntacticAnalyzerDepsHetero::recopyCoordinationStrings";
329#endif
330
331 // Initialisation
332 auto syntacticData = std::dynamic_pointer_cast<SyntacticData>(analysis.getData("SyntacticData"));
333 if (syntacticData==0)
334 {
336 LERROR << "no syntacticData ! abort";
337 return MISSING_DATA;
338 }
339
340 auto simplificationData = std::dynamic_pointer_cast<SimplificationData>(analysis.getData("SimplificationData"));
341 if (simplificationData==0)
342 {
344 LERROR << "no simplificationData ! abort";
345 return MISSING_DATA;
346 }
347
348 DependencyGraph *depGraph = syntacticData-> dependencyGraph();
349 EdgeDepRelTypePropertyMap relTypeMap = get(edge_deprel_type, *depGraph);
350
351 // for each string definition d
352 for (std::map< std::string, std::vector< LinguisticGraphVertex > >::const_iterator dit = simplificationData->coordStringsDefs().begin(); dit != simplificationData->coordStringsDefs().end(); dit++)
353 {
354 if (simplificationData->coordStrings().find((*dit).first) == simplificationData->coordStrings().end())
355 {
356 // no same string for definition
357#ifdef DEBUG_LP
358 LDEBUG << "SyntacticAnalyzerDepsHetero::recopyCoordinationStrings no same string for definition " << (*dit).first;
359#endif
360 continue;
361 }
362 const std::vector< LinguisticGraphVertex >& stringDef = (*dit).second;
363 const std::vector< std::vector< LinguisticGraphVertex > >& sameStrings = (*simplificationData->coordStrings().find((*dit).first)).second;
364#ifdef DEBUG_LP
365 LDEBUG << "SyntacticAnalyzerDepsHetero::recopyCoordinationStrings there is " << sameStrings.size() << " same strings for " << (*dit).first;
366 #endif
367 // for each same string s of d
368 for (std::vector< std::vector< LinguisticGraphVertex > >::const_iterator ssit = sameStrings.begin(); ssit != sameStrings.end(); ssit++)
369 {
370 const std::vector< LinguisticGraphVertex >& sameString = *ssit;
371 std::vector< LinguisticGraphVertex >::const_iterator stringDefIt = stringDef.begin();
372 std::vector< LinguisticGraphVertex >::const_iterator sameStringIt = sameString.begin();
373 // for each twin vertices vs and vd in s and d
374 for (; stringDefIt != stringDef.end(); stringDefIt++, sameStringIt++)
375 {
376 LinguisticGraphVertex stringDefVx = *stringDefIt;
377 LinguisticGraphVertex sameStringVx = *sameStringIt;
378 DependencyGraphVertex depStringDefVx = syntacticData->depVertexForTokenVertex(stringDefVx);
379 DependencyGraphVertex depSameStringVx = syntacticData->depVertexForTokenVertex(sameStringVx);
380
381 // if vd has outgoing edges from outside of d that vs doest not have (same source and
382 // same type), create this edge for vs
383 DependencyGraphOutEdgeIt depIt, depIt_end;
384 boost::tie(depIt, depIt_end) = out_edges(depStringDefVx, *depGraph);
385 for (; depIt != depIt_end; depIt++)
386 {
387 DependencyGraphVertex depTargV = target(*depIt, *depGraph);
388 // target must be outside current coord definition string
389 if (std::find(stringDef.begin(), stringDef.end(), depTargV) != stringDef.end()) continue;
390 std::string relationName = static_cast<const Common::MediaticData::LanguageData&>(Common::MediaticData::MediaticData::single().mediaData(m_language)).getSyntacticRelationName(relTypeMap[*depIt]);
391 std::pair< LinguisticGraphEdge, bool > sameStringEdge = boost::edge(depSameStringVx, depTargV, *depGraph);
392 if (!sameStringEdge.second)
393 {
394#ifdef DEBUG_LP
395 LDEBUG << "SyntacticAnalyzerDepsHetero::recopyCoordinationStrings create edge " << depSameStringVx << " -("<<relationName<<")-> " << depTargV;
396#endif
397 std::pair<DependencyGraphEdge,bool> newSameStringEdge = boost::add_edge(depSameStringVx, depTargV, *depGraph);
398 if (newSameStringEdge.second)
399 {
400 relTypeMap[newSameStringEdge.first] = relTypeMap[*depIt];
401 }
402 }
403 }
404 // same thing for incoming edges
405 DependencyGraphInEdgeIt depInIt, depInIt_end;
406 boost::tie(depInIt, depInIt_end) = in_edges(depStringDefVx, *depGraph);
407 for (; depInIt != depInIt_end; depInIt++)
408 {
409 DependencyGraphVertex depSrcV = source(*depInIt, *depGraph);
410 // target must be outside current coord definition string
411 if (std::find(stringDef.begin(), stringDef.end(), depSrcV) != stringDef.end()) continue;
412 std::string relationName = static_cast<const Common::MediaticData::LanguageData&>(Common::MediaticData::MediaticData::single().mediaData(m_language)).getSyntacticRelationName(relTypeMap[*depIt]);
413 std::pair< LinguisticGraphEdge, bool > sameStringEdge = boost::edge(depSameStringVx, depSrcV, *depGraph);
414 if (!sameStringEdge.second)
415 {
416 std::pair<DependencyGraphEdge,bool> newSameStringEdge = boost::add_edge(depSameStringVx, depSrcV, *depGraph);
417 if (newSameStringEdge.second)
418 {
419#ifdef DEBUG_LP
420 LDEBUG << "SyntacticAnalyzerDepsHetero::recopyCoordinationStrings create edge " << depSameStringVx << " <-("<<relationName<<")- " << depSrcV;
421#endif
422 relTypeMap[newSameStringEdge.first] = relTypeMap[*depInIt];
423 }
424 }
425 }
426 }
427 }
428 }
429 return SUCCESS_ID;
430}
431
432
433} // end namespace
434} // end namespace
435} // end namespace
DependencyGraph::in_edge_iterator DependencyGraphInEdgeIt
DependencyGraph::out_edge_iterator DependencyGraphOutEdgeIt
boost::property_map< DependencyGraph, edge_deprel_type_t >::type EdgeDepRelTypePropertyMap
DependencyGraph::vertex_descriptor DependencyGraphVertex
boost::adjacency_list< boost::vecS, boost::vecS, boost::bidirectionalS, DepVertexProperties, DepEdgeProperties > DependencyGraph
The dependency graph class.
@ edge_deprel_type
#define LWARN
Definition LimaCommon.h:160
#define LDEBUG
Definition LimaCommon.h:157
#define LINFO
Definition LimaCommon.h:158
#define LERROR
Definition LimaCommon.h:161
boost::graph_traits< LinguisticGraph >::edge_descriptor LinguisticGraphEdge
typedefs to simplify the access to various graphs elements
LinguisticGraph::vertex_descriptor LinguisticGraphVertex
boost::adjacency_list< boost::vecS, boost::vecS, boost::bidirectionalS, LinguisticVertexProperties > LinguisticGraph
Property to identify the chains in the graph.
Defines a Factory to create Object of type Base.
Data used for the simplification of sentences allowing easier heterosyntagmatic analysis.
#define SAHLOGINIT
process unit to extract heterosyntagmatic dependency relations
#define SYNTACTICANALYZERDEPSHETERO_CLASSID
Holds all data that pass through the ProcessUnits Analysis data are shared pointers,...
std::shared_ptr< AnalysisData > getData(const QString &id)
return AnalysisData by id
void setData(const QString &id, std::shared_ptr< AnalysisData > data)
set an analysisData with the given id.
Holds linguistic data for one language.
const MediaData & mediaData(MediaId media) const
std::map< std::string, std::string > & getMapAtKey(const std::string &key)
return a message when a 'param' was not found
Manage initialization of InitializableObjects using configuration module and parameters.
const InitializationParameters & getInitializationParameters() const
get Initialization Parameters
std::map< Common::MediaticData::SyntacticRelationId, std::shared_ptr< Automaton::Recognizer > > m_subSentRecognizers
void init(Common::XMLConfigurationFiles::GroupConfigurationStructure &unitConfiguration, Manager *manager) override
initialize with parameters from configuration file.
LimaStatusCode process(AnalysisContent &analysis) const override
Process on data in analysisContent.
SyntacticAnalyzerDepsHetero & operator=(const SyntacticAnalyzerDepsHetero &)
static const LinguisticResources & single()
const singleton accessor
Definition Singleton.h:51
This file contains a class to control log of informations about time, such as logging cumulated time ...
SimpleFactory< MediaProcessUnit, SyntacticAnalyzerDepsHetero > syntacticAnalyzerDepsHeteroFactory(SYNTACTICANALYZERDEPSHETERO_CLASSID)
NAUTITIA.
LimaStatusCode
Definition LimaCommon.h:236
@ SUCCESS_ID
Definition LimaCommon.h:237
@ INVALID_CONFIGURATION
Definition LimaCommon.h:242
@ MISSING_DATA
Definition LimaCommon.h:243
STL namespace.