LIMA
Libre Multilingual Analyzer — C++ API
Loading...
Searching...
No Matches
rule.cpp
Go to the documentation of this file.
1// Copyright 2002-2020 CEA LIST
2// SPDX-FileCopyrightText: 2022 CEA LIST <gael.de-chalendar@cea.fr>
3//
4// SPDX-License-Identifier: MIT
5
6/************************************************************************
7*
8* File : rule.cpp
9* Author : Romaric Besan�n (besanconr@zoe.cea.fr)
10* Created on : Tue Oct 15 2002
11* Copyright : (c) 2002 by CEA
12* Version : $Id$
13*
14*************************************************************************/
15
16#include "rule.h"
17#include "automaton.h"
19#include<iostream>
20#include<string>
21
22using namespace std;
24
25namespace Lima {
26namespace LinguisticProcessing {
27namespace Automaton {
28
29/***********************************************************************/
30// constructors
31/***********************************************************************/
33 m_trigger(0),
34 m_left(),
35 m_right(),
36 m_type(),
37 m_normalizedForm(),
38 m_numberOfConstraints(0),
39 m_contextual(true),
40 m_negative(false),
41 m_hasLeftRightConstraint(false),
42 m_actions(),
43 m_actionsWithOneArgument(),
44 m_weight(0.0),
45 m_ruleId("")
46{
47}
48
49Rule::Rule(const Rule& r):
50 m_trigger(r.m_trigger->clone()),
51 m_left(r.m_left),
52 m_right(r.m_right),
53 m_type(r.m_type),
54 m_lingProp(r.m_lingProp),
55 m_normalizedForm(r.m_normalizedForm),
56 m_numberOfConstraints(r.m_numberOfConstraints),
57 m_contextual(r.m_contextual),
58 m_negative(r.m_negative),
59 m_hasLeftRightConstraint(r.m_hasLeftRightConstraint),
60 m_actions(r.m_actions),
61 m_actionsWithOneArgument(r.m_actionsWithOneArgument),
62 m_weight(r.m_weight),
63 m_ruleId(r.m_ruleId)
64{
65}
66
67// read a rule from a text entry
68// Rule::Rule(const LimaString& s, Tchar sep) {
69// // std::cerr << "building rule from string " << s << endl;
70// *this=RuleCompiler::buildRule(s,sep);
71// }
72
73/***********************************************************************/
74// destructor
75/***********************************************************************/
77 freeMem();
78}
79
96
97/***********************************************************************/
98// copy
99/***********************************************************************/
101 if (this != &r) {
102 freeMem();
103 init();
104 copy(r);
105 }
106 return (*this);
107}
108
109bool Rule::operator<(const Rule& r) {
110 return (m_weight<r.m_weight);
111}
112
113//**********************************************************************
114// helper functions for constructors and destructors
116{
117 m_trigger=0;
122 m_normalizedForm.clear();
124 m_contextual=true;
125 m_negative=false;
127 m_actions=std::vector<Constraint>();
128 m_actionsWithOneArgument=std::vector<std::pair<LimaString,Constraint> >();
129 m_weight=0.0;
130 m_ruleId="";
131}
132
150
152{
153 if (m_trigger != 0) {
154 delete m_trigger;
155 }
156 m_trigger=0;
157}
158
159//**********************************************************************
160// test the rule on a graph
161//**********************************************************************
163 const LinguisticGraphVertex& leftContext,
164 const LinguisticGraphVertex& rightContext,
165 const LinguisticGraphVertex& leftLimit,
166 const LinguisticGraphVertex& rightLimit,
167 AnalysisContent& analysis,
168 RecognizerMatch& leftmatch,
169 RecognizerMatch& rightmatch,
170 ConstraintCheckList& constraintCheckList,
171 ForwardSearch& forward,
172 BackwardSearch& backward,
173 const AutomatonControlParams& controlParams) const {
174
176
177 // do not need to get all matches from left part:
178 // matches on left and right parts are independant
179 if (! m_left.getBestMatch(graph, leftContext, leftLimit,
180 analysis,leftmatch,
181 constraintCheckList,
182 BACKWARDSEARCH, controlParams)) {
183/* AULOGINIT;
184 LDEBUG << "no match found on the left part";*/
185 return false;
186 }
187 if (! m_right.getBestMatch(graph, rightContext, rightLimit,
188 analysis,rightmatch,
189 constraintCheckList,
190 FORWARDSEARCH, controlParams)) {
191/* AULOGINIT;
192 LDEBUG << "no match found on the right part";*/
193 return false;
194 }
195
196 return true;
197 }
198
199 // else has to store all possible left matches to
200 // get best right match wrt each left match
201
203 if (! m_left.getAllMatches(graph, leftContext, leftLimit,
204 analysis,leftMatches,
205 constraintCheckList,forward,backward,
206 BACKWARDSEARCH, controlParams)) {
207/* AULOGINIT;
208 LDEBUG << "no match found on the left part";*/
209 return false;
210 }
211// AULOGINIT;
212// LDEBUG << "Rule: found " << leftMatches.size()
213// << " matches for left part";
214
215 Automaton::AutomatonMatchSet::const_iterator
216 currentLeftMatch=leftMatches.begin(),
217 endLeftMatch=leftMatches.end();
218
219 // store checklists (to avoid testing right part with same
220 // checklists)
221 std::set<ConstraintCheckList> leftCheckLists;
222
223 for (; currentLeftMatch!=endLeftMatch; currentLeftMatch++) {
224
225// LDEBUG << "Rule: looking at right part with left="
226// << (*currentLeftMatch).first << ",checklist="
227// << (*currentLeftMatch).second;
228
229 if (leftCheckLists.find((*currentLeftMatch).second)!=
230 leftCheckLists.end()) {
231 continue;
232 }
233 // must copy constraintCheckList to modify it
234 // because iterator in set are not mutable
235 constraintCheckList=(*currentLeftMatch).second;
236 if (m_right.getBestMatch(graph, rightContext, rightLimit,
237 analysis,rightmatch,constraintCheckList,
238 FORWARDSEARCH, controlParams)) {
239 leftmatch=(*currentLeftMatch).first;
240 // has to reverse left match (to be in natural sense of the graph)
241 std::reverse(leftmatch.begin(),leftmatch.end());
242
243 return true;
244 }
245 leftCheckLists.insert((*currentLeftMatch).second);
246 }
247 return false;
248}
249
251 AnalysisContent& analysis,
252 ConstraintCheckList& constraintCheckList,
253 const bool success,
254 RecognizerMatch* result) const {
255
256 if (m_actions.empty()) {
257 return true;
258 }
259
260#ifdef DEBUG_LP
261 AULOGINIT;
262 LDEBUG << "Rule::executeActions: start";
263 if (NULL != result)
264 LDEBUG << "result = " << *result;
265 else
266 LDEBUG << "result = NULL";
267#endif
268/*
269 * for( std::vector<MatchElement>::iterator matchElmt = result->begin() ;
270 matchElmt != result->end() ; matchElmt++ ) {
271 }
272*/
273 // execute actions with 1 argument associated to the rule
274 for (std::vector<std::pair<LimaString,Constraint> >::const_iterator actionItr=m_actionsWithOneArgument.begin();
275 actionItr!=m_actionsWithOneArgument.end(); actionItr++) {
276 const ConstraintAction& action = actionItr->second.action();
277 // test if execution of action is required
278#ifdef DEBUG_LP
279 LDEBUG << "Rule::executeActions: success = " << success
280 << ", check if execution is required for function " << actionItr->second.functionName();
281#endif
282 if( (( success ) && (action==EXECUTE_IF_SUCCESS || action==EXECUTE_IF_SUCCESS_REVERSE))
283 || (( !success ) && (action==EXECUTE_IF_FAILURE || action==EXECUTE_IF_FAILURE_REVERSE)) ) {
284 const LimaString& ruelElemtId = actionItr->first;
285#ifdef DEBUG_LP
286 LDEBUG << "Rule::executeActions: check " << ruelElemtId << "for function " << actionItr->second.functionName();
287#endif
288 const ConstraintFunction* functionAddr = actionItr->second.functionAddr();
289 // search for vertex which match same ruleElemntId as actionItr
290 for( std::vector<MatchElement>::iterator matchElmt = result->begin() ;
291 matchElmt != result->end() ; matchElmt++ ) {
292#ifdef DEBUG_LP
293 LDEBUG << "Rule::executeActions: check vertex "
294 << matchElmt->m_elem.first << " with " << matchElmt->getRuleElemtId();
295#endif
296 if( (matchElmt->getRuleElemtId()).startsWith(ruelElemtId) ) {
297#ifdef DEBUG_LP
298 LDEBUG << "Rule::executeActions: found " << matchElmt->m_elem.first;
299#endif
300 bool ok=(*functionAddr)(graph,matchElmt->m_elem.first,analysis);
301 if (!ok) {
302 AULOGINIT;
303 LERROR << "Rule::executeActions: execution of function" << actionItr->second.functionName() << "failed";
304 }
305 }
306 }
307 }
308 else {
309#ifdef DEBUG_LP
310 LDEBUG << "Rule::executeActions: execution of function" << actionItr->second.functionName() << "not required";
311#endif
312 }
313 }
314 // execute actions without arguments associated to the rule
315 // even if rule failed (actions are internally conditionned by success)
316 for (std::vector<Constraint>::const_iterator action=m_actions.begin();
317 action!=m_actions.end(); action++) {
318// LDEBUG << "Applying action " << action->functionName();
319 if (! (*action).apply(graph,analysis,
320 constraintCheckList,
321 success,
322 result)) {
323// LDEBUG << "a match was found but an action has not succeeded"
324// << " -> returned false";
325 return false;
326 }
327 }
328 return true;
329}
330
331//**********************************************************************
332// output
333ostream& operator << (ostream& os, const Rule& r) {
334 os << r.getRuleId() << ":" << endl;
335 os << "trigger=" << *(r.getTrigger()) << "(w=" << (r.getWeight())<< "):" << endl;
336 os << "left=" << endl << r.leftAutomaton();
337 os << "right=" << endl << r.rightAutomaton();
338 os << "entityType:" << r.getType() << "; lingPropeties:" << r.getLinguisticProperties().toString() << endl;
339 for (std::vector<Constraint>::const_iterator action=r.m_actions.begin();
340 action!=r.m_actions.end(); action++) {
341 os << *action << endl;
342 }
343 for (std::vector<std::pair<LimaString,Constraint> >::const_iterator action=r.m_actionsWithOneArgument.begin();
344 action!=r.m_actionsWithOneArgument.end(); action++) {
345 os << "(" << (*action).first.toUtf8().data() << ","<< (*action).second<< ")" << endl;
346 }
347 return os;
348}
349QDebug& operator << (QDebug& os, const Rule& r) {
350 os << r.getRuleId() << ":" << QTENDL;
351 os << "trigger=" << *(r.getTrigger()) << "(w=" << (r.getWeight())<< "):" << QTENDL;
352 os << "left=" << QTENDL << r.leftAutomaton();
353 os << "right=" << QTENDL << r.rightAutomaton();
354 os << "entityType:" << r.getType() << "; lingPropeties:" << r.getLinguisticProperties() << QTENDL;
355 for (std::vector<Constraint>::const_iterator action=r.m_actions.begin();
356 action!=r.m_actions.end(); action++) {
357 os << *action << QTENDL;
358 }
359 for (std::vector<std::pair<LimaString,Constraint> >::const_iterator action=r.m_actionsWithOneArgument.begin();
360 action!=r.m_actionsWithOneArgument.end(); action++) {
361 os << "(" << action->first << ","<< action->second<< ")" << QTENDL;
362 }
363 return os;
364}
365
366} // namespace end
367} // namespace end
368} // namespace end
#define QTENDL
Definition LimaCommon.h:32
#define LDEBUG
Definition LimaCommon.h:157
#define LERROR
Definition LimaCommon.h:161
LinguisticGraph::vertex_descriptor LinguisticGraphVertex
#define AULOGINIT
#define L_NONE
Definition StdBitset.h:338
Holds all data that pass through the ProcessUnits Analysis data are shared pointers,...
std::string toString() const
Definition StdBitset.h:152
␈rief a class for control parameters for the search using the automata
Definition automaton.h:44
␈rief A class for the description of automata
Definition automaton.h:87
bool getBestMatch(const LinguisticAnalysisStructure::AnalysisGraph &graph, const LinguisticGraphVertex &begin, const LinguisticGraphVertex &limit, AnalysisContent &analysis, RecognizerMatch &longestMatch, ConstraintCheckList &checkList, const SearchGraphSense sense, const AutomatonControlParams &controlParams) const
test if a text corresponds to the automaton : the text is represented as a LinguisticAnalysisStructur...
bool getAllMatches(const LinguisticAnalysisStructure::AnalysisGraph &graph, const LinguisticGraphVertex &begin, const LinguisticGraphVertex &limit, AnalysisContent &analysis, AutomatonMatchSet &allMatches, ConstraintCheckList &checkList, ForwardSearch &forward, BackwardSearch &backward, const SearchGraphSense sense, const AutomatonControlParams &controlParams) const
get all matches found between automaton and graph between two points (WARNING: in case of backward se...
void reinit()
reinitializes the automaton (no states, no transitions)
std::set< AutomatonMatch, CompareAutomatonMatch > AutomatonMatchSet
Definition automaton.h:203
Automaton const & leftAutomaton() const
Definition rule.h:158
Automaton const & rightAutomaton() const
Definition rule.h:159
const std::string & getRuleId() const
Definition rule.h:67
std::vector< Constraint > m_actions
Definition rule.h:139
LinguisticCode getLinguisticProperties() const
Definition rule.h:161
const LimaString & getNormalizedForm() const
Definition rule.h:163
Common::MediaticData::EntityType m_type
Definition rule.h:128
const std::vector< Constraint > & getActions() const
Definition rule.h:167
TransitionUnit * getTrigger() const
Definition rule.h:157
bool test(const LinguisticProcessing::LinguisticAnalysisStructure::AnalysisGraph &graph, const LinguisticGraphVertex &leftContext, const LinguisticGraphVertex &rightContext, const LinguisticGraphVertex &leftLimit, const LinguisticGraphVertex &rightLimit, AnalysisContent &analysis, RecognizerMatch &leftmatch, RecognizerMatch &rightmatch, ConstraintCheckList &, ForwardSearch &forward, BackwardSearch &backward, const AutomatonControlParams &controlParams) const
test the rule on a morphological graph : the trigger has already been tested: test only left and righ...
Definition rule.cpp:162
std::vector< std::pair< LimaString, Constraint > > m_actionsWithOneArgument
Definition rule.h:140
Common::MediaticData::EntityType getType() const
Definition rule.h:160
bool executeActions(const LinguisticAnalysisStructure::AnalysisGraph &graph, AnalysisContent &analysis, ConstraintCheckList &constraintCheckList, const bool success, RecognizerMatch *result) const
Definition rule.cpp:250
const std::vector< std::pair< LimaString, Constraint > > & getActionsWithOneArgument() const
Definition rule.h:170
virtual TransitionUnit * clone() const =0
An AnalysisData containing a LinguisticGraph with a language and an id.
std::ostream & operator<<(std::ostream &os, const DFFSPos &x)
@ FORWARDSEARCH
forward search in the graph
Definition searchGraph.h:36
@ BACKWARDSEARCH
backward search in the graph
Definition searchGraph.h:37
std::vector< ConstraintCheckListElement > ConstraintCheckList
NAUTITIA.
QString LimaString
Definition LimaString.h:33
STL namespace.