34namespace LinguisticProcessing
59 LERROR <<
"No 'scope' defined in "<<unitConfiguration.
getName()<<
" configuration group for language " << (int)
m_language;
61 LERROR <<
"Scope is set to 3 by default.";
68 LERROR <<
"No 'threshold' defined in "<<unitConfiguration.
getName()<<
" configuration group for language " << (int)
m_language;
70 LERROR <<
"Threshold is set to 130 by default.";
78 LERROR <<
"Please define 'Resolve Definites' and 'Resolve non third person pronouns' in "<<unitConfiguration.
getName()<<
" configuration group for language " << (int)
m_language;
81 LERROR <<
"Resolve Definites is set to true (1) by default.";
82 LERROR <<
"Resolve non third person pronouns is set to false (0) by default.";
95 std::map<string, string> tmpMap = unitConfiguration.
getMapAtKey(
"MacroCategories");
96 for (map<string, string>::const_iterator it = tmpMap.begin(); it!=tmpMap.end(); it++)
100 for (deque<string>::const_iterator it = tmpDeque.begin(); it!=tmpDeque.end(); it++)
107 for (deque<string>::const_iterator it = tmpDeque.begin(); it!=tmpDeque.end(); it++)
114 for (deque<string>::const_iterator it = tmpDeque.begin(); it!=tmpDeque.end(); it++)
122 LERROR <<
"One of the tags list is not defined in "<<unitConfiguration.
getName()<<
" configuration group for language " << (int)
m_language;
123 LERROR <<
"Please check all of the following categories:";
124 LERROR <<
"'LexicalAnaphora', 'UndefinitePronouns', 'PossessivePronouns'.";
141 LERROR <<
"One of the macro relation is not defined in "<<unitConfiguration.
getName()<<
" configuration group for language " << (int)
m_language;
142 LERROR <<
"Please check all of the following relations:";
143 LERROR <<
"'PrepRelation', 'PleonasticRelation', 'DefiniteRelation', 'SubjectRelation', 'AttributeRelation', 'CODRelation', 'COIRelation', 'AdjunctRelation', 'AgentRelation', 'NPDeterminerRelation'.";
150 const std::map<std::string,std::string>& salience=unitConfiguration.
getMapAtKey(
"SalienceFactors");
151 for (std::map<std::string,std::string>::const_iterator it=salience.begin();
160 LERROR <<
"No map 'SalienceFactors' in "<<unitConfiguration.
getName()<<
" configuration group for language " << (int)
m_language;
167 const std::map<std::string,std::string>& slotValuesStr=unitConfiguration.
getMapAtKey(
"SlotValues");
168 for (std::map<std::string,std::string>::const_iterator it=slotValuesStr.begin();
169 it!=slotValuesStr.end();
177 LERROR <<
"No map 'SlotValues' in "<<unitConfiguration.
getName()<<
" configuration group for language " << (int)
m_language;
194 LINFO <<
"start CorefSolver";
197 auto posgraph = std::dynamic_pointer_cast<AnalysisGraph>(analysis.
getData(
"PosGraph"));
201 LERROR <<
"no PosGraph ! abort";
204 auto sb = std::dynamic_pointer_cast<SegmentationData>(analysis.
getData(
"SentenceBoundaries"));
208 LERROR <<
"no sentence bounds ! abort";
211 if (sb->getGraphId() !=
"PosGraph")
214 LERROR <<
"SentenceBounds computed on graph '" << sb->getGraphId() <<
"'. CorefSolver needs " <<
215 "sentence bounds on PosGraph";
218 auto syntacticData = std::dynamic_pointer_cast<SyntacticData>(analysis.
getData(
"SyntacticData"));
222 LERROR <<
"no syntactic data ! abort";
228 auto annotationData = std::dynamic_pointer_cast<AnnotationData>(analysis.
getData(
"AnnotationData"));
229 if (annotationData == 0)
231 annotationData = std::make_shared<AnnotationData>();
235 if (std::dynamic_pointer_cast<AnalysisGraph>(analysis.
getData(
"AnalysisGraph")) != 0)
237 std::dynamic_pointer_cast<AnalysisGraph>(analysis.
getData(
"AnalysisGraph"))->populateAnnotationGraph(
238 annotationData.get(),
"AnalysisGraph");
240 if (std::dynamic_pointer_cast<AnalysisGraph>(analysis.
getData(
"PosGraph")) != 0)
243 std::dynamic_pointer_cast<AnalysisGraph>(analysis.
getData(
"PosGraph"))->populateAnnotationGraph(
244 annotationData.get(),
"PosGraph");
247 analysis.
setData(
"AnnotationData",annotationData);
272 if (annotationData->dumpFunction(
"Coreferent") == 0)
274 annotationData->dumpFunction(
"Coreferent",
new DumpCoreferent(annotationData.get()));
281 std::deque<std::vector<CoreferentAnnotation> > npVertices;
282 std::deque<Vertices>* npCandidates =
new std::deque<Vertices>();
286 uint64_t nextReferentId = 1;
287 std::set< LinguisticGraphVertex > alreadyProcessedVertices;
293 for (std::vector<Segment>::const_iterator boundItr=(sb->getSegments()).begin();
294 boundItr!=(sb->getSegments()).end();
310 npVertices.push_front(std::vector<CoreferentAnnotation>());
311 npCandidates->push_front(
Vertices());
314 npVertices.pop_back();
315 if (npCandidates->size()>
m_scope)
316 npCandidates->pop_back();
318 for (std::deque<Vertices>::iterator itm = npCandidates->begin();
319 itm != npCandidates->end( );
322 for (Vertices::iterator candidateItr = (*itm).begin( );
323 candidateItr != (*itm).end( );
326 (*candidateItr)->salience((*candidateItr)->salience()/2);
331 LDEBUG <<
"analyze sentence from vertex " << beginSentence <<
" to vertex " << endSentence;
338 while (v!=endSentence)
340 if (alreadyProcessedVertices.find(v) != alreadyProcessedVertices.end())
346 (*npVertices.begin()).push_back(ca);
347 alreadyProcessedVertices.insert(v);
350 beginSentence=endSentence;
352 boost::tie(ite, ite_end)=boost::out_edges(v, *graph);
353 v=target(*ite, *graph);
360 LDEBUG <<
"classify NPs and calculate salience weights";
362 for(vector<CoreferentAnnotation>::iterator itca = (*npVertices.begin()).begin();
363 itca!=(*npVertices.begin()).end();
366 (*itca).newerRef(&(*itca));
371 if (classif == 1 || classif == 11)
373 npAnaphora->insert(&(*itca));
375 if (classif == 10 || classif == 11)
377 (*npCandidates->begin()).insert(&(*itca));
389 for (Vertices::iterator anaphItr=npAnaphora->begin();
390 anaphItr!=npAnaphora->end();
397 for (std::deque<Vertices>::iterator itm = npCandidates->begin( );
398 itm != npCandidates->end( );
401 for (Vertices::iterator itc = (*itm).begin( );
402 itc != (*itm).end( );
407 LDEBUG <<
"initialize syntactic filter";
409 initSyntacticFilter(analysis, posgraph.get(), syntacticData.get(), npAnaphora, npCandidates, roBinding);
415 LDEBUG<<
"RuledOutBinding:";
416 for (VerticesRelation::iterator itro = roBinding->begin( );
417 itro != roBinding->end( );
421 for (std::set<CoreferentAnnotation*>::iterator its = (*itro).second.begin( );
422 its != (*itro).second.end( );
428 LDEBUG <<
"initialize lexical anaphora binding";
430 bindingLexicalAnaphora(analysis,posgraph.get(), syntacticData.get(), npAnaphora, npCandidates, lexAnaBinding);
436 LDEBUG<<
"Lexical Anaphora Binding:";
437 for (WeightedVerticesRelation::iterator itp = lexAnaBinding->begin( );
438 itp != lexAnaBinding->end( );
442 for (std::map<CoreferentAnnotation*, float>::iterator its = (*itp).second.begin( );
443 its != (*itp).second.end( );
448 LDEBUG <<
"resolve lexical anaphora";
450 getBest(syntacticData.get(), posgraph.get(), lexAnaBinding, npCandidates, annotationData.get());
457 LDEBUG <<
"initialize potential binding";
459 bindingPotentialCandidates(posgraph.get(), npAnaphora, npCandidates, pBinding);
462 LDEBUG <<
"adjust local saliences";
464 adjustSaliences(syntacticData.get(), npCandidates, pBinding, endSentence, posgraph.get(), analysis);
467 LDEBUG<<
"Potential Binding:";
468 for (WeightedVerticesRelation::iterator itp = pBinding->begin( );
469 itp != pBinding->end( );
473 for (std::map<CoreferentAnnotation*, float>::iterator its = (*itp).second.begin( );
474 its != (*itp).second.end( );
477 LDEBUG <<(*its).first->morphVertex()<<
" - "
479 <<
" : " << (*its).second;
486 LDEBUG <<
"apply threshold filter";
488 applyThresholdFilter(pBinding);
491 LDEBUG <<
"apply circular filter";
493 applyCircularFilter(pBinding);
496 LDEBUG <<
"apply morphosyntactic filter";
498 applyMorphoSyntacticFilter(pBinding,roBinding);
503 LDEBUG <<
"resolve binding";
505 getBest(syntacticData.get(), posgraph.get(), pBinding,npCandidates, annotationData.get());
512 delete lexAnaBinding;
516 LDEBUG <<
"write coreferent annotations on graph";
526void CorefSolver::initSyntacticFilter(
531 std::deque<CoreferentAnnotation::Vertices>* npCandidates,
539 for (Vertices::iterator anaphItr=npAnaphora->begin();
540 anaphItr!=npAnaphora->end();
544 std::set<CoreferentAnnotation*> tmpCandidate;
545 for (std::deque<Vertices>::iterator itm = npCandidates->begin();
546 itm != npCandidates->end( );
548 for (Vertices::iterator candidateItr = (*itm).begin( );
549 candidateItr != (*itm).end( );
561 (*npCandidates->begin()).find(*candidateItr)!=(*npCandidates->begin()).end()
566 (*anaphItr)->isInTheArgumentDomainOf(**candidateItr, syntacticData,
m_language, anagraph, ac,
568 new set<LinguisticGraphVertex>())
590 tmpCandidate.insert(*candidateItr);
593 roBinding->insert(make_pair(*anaphItr, tmpCandidate));
594 tmpCandidate.clear();
598 void CorefSolver::bindingLexicalAnaphora(
603 std::deque<CoreferentAnnotation::Vertices>* npCandidates,
611 for (Vertices::iterator anaphItr=npAnaphora->begin();
612 anaphItr!=npAnaphora->end();
619 std::map<CoreferentAnnotation*, float> tmpCandidate;
620 for (std::deque<Vertices>::iterator itm = npCandidates->begin();
621 itm != npCandidates->end( );
623 for (Vertices::iterator candidateItr = (*itm).begin( );
624 candidateItr != (*itm).end( );
630 (*anaphItr)->morphVertex() != (*candidateItr)->morphVertex() &&
636 (*candidateItr)->morphVertex(),ac) ||
641 new set<LinguisticGraphVertex>()) ||
664 tmpCandidate.insert(make_pair(*candidateItr, (*candidateItr)->salience()));
667 lexAnaBinding->insert(make_pair(*anaphItr, tmpCandidate));
672 void CorefSolver::bindingPotentialCandidates(
675 std::deque<Vertices>* npCandidates,
680 applyEquivalentClassFilter(graph,npCandidates);
682 for (Vertices::iterator anaphItr=npAnaphora->begin();
683 anaphItr!=npAnaphora->end();
690 for (std::deque<Vertices>::iterator itm = npCandidates->begin();
691 itm != npCandidates->end( );
694 for (Vertices::iterator candidateItr = (*itm).begin( );
695 candidateItr != (*itm).end( );
698 WeightedVerticesRelation::iterator tmpBinding = pBinding->find(*anaphItr);
699 if (tmpBinding==pBinding->end())
701 std::map <CoreferentAnnotation*,float> tmpMap;
702 tmpMap.insert(make_pair(*candidateItr,(*candidateItr)->salience()));
703 pBinding->insert(make_pair(*anaphItr,tmpMap));
707 (*tmpBinding).second.insert(make_pair(*candidateItr,(*candidateItr)->salience()));
714void CorefSolver::getBest(
719 std::deque<CoreferentAnnotation::Vertices>* npCandidates,
724 LDEBUG <<
"CorefSolver::getBest binding size = " << binding->size();
727 for (WeightedVerticesRelation::iterator itp = binding->begin( );
728 itp != binding->end( );
732 LDEBUG <<
" outer for loop on " << (*itp).first->morphVertex();
736 CoreferentAnnotation* ca2erase = 0;
737 std::pair<CoreferentAnnotation, CoreferentAnnotation> tmpPair;
738 for (std::map<CoreferentAnnotation*, float>::iterator its = (*itp).second.begin( );
739 its != (*itp).second.end( );
743 LDEBUG <<
" looking at " << (*itp).first->morphVertex() <<
" ("<<(*itp).first->bindingSalience()<<
") -> " << (*its).first->morphVertex() <<
" ("<<(*its).second<<
")";
745 if ((*its).second>=(*itp).first->bindingSalience())
747 (*itp).first->bindingSalience((*its).second);
748 tmpPair = make_pair(*(*itp).first, *(*its).first);
749 ca2erase = (*its).first;
756 if ((*itp).first!=(*its).first && (!((*its).first)->isTaggedAsOneOfThese(graph,
m_reflexiveReciprocal,
m_microAccessor)) && (*itp).first->referentType(sd,anagraph->
getGraph(),
m_macroAccessor,
m_microAccessor,
m_tagLocalDef,
m_relLocalDef,
m_definiteCategs,
m_reflexiveReciprocal,
m_undefPronouns,
m_possPronouns,
m_personAccessor,anagraph,
m_language)!=
"def" &&
768 tmpPair.first.writeAnnotation(ad, tmpPair.second);
772 for (std::deque<Vertices>::iterator itm = npCandidates->begin();
773 itm != npCandidates->end( );
776 if ((*itm).find(ca2erase)!=(*itm).end())
778 (*(*itm).find(ca2erase))->newerRef((*itp).first);
782 for (WeightedVerticesRelation::iterator itp2 = binding->begin( );
783 itp2 != binding->end( );
787 LDEBUG <<
" erasing " << (*itp2).first->morphVertex() <<
" -> " << ca2erase->morphVertex();
789 (*itp2).second.erase(ca2erase);
797 void CorefSolver::applyEquivalentClassFilter(
799 std::deque<CoreferentAnnotation::Vertices>* npCandidates)
const
802 std::set<CoreferentAnnotation*> candidates2erase;
803 for (std::deque<Vertices>::iterator itm = npCandidates->begin();
804 itm != npCandidates->end( );
807 for (Vertices::iterator candidateItr = (*itm).begin( );
808 candidateItr != (*itm).end( );
814 candidates2erase.insert(*candidateItr);
818 for (std::set<CoreferentAnnotation*>::iterator itE = candidates2erase.begin();
819 itE != candidates2erase.end( );
821 for (std::deque<Vertices>::iterator itm = npCandidates->begin();
822 itm != npCandidates->end( );
826 for (std::set<CoreferentAnnotation*>::iterator itm2 = (*itm).begin();
827 itm2 != (*itm).end( );
830 if ((*itm2)==(*itE)->newerRef() && (*itE)->salience()>(*itm2)->salience())
832 (*itm2)->salience((*itE)->salience());
841void CorefSolver::adjustSaliences(
843 std::deque<Vertices>* npCandidates,
855 for (WeightedVerticesRelation::iterator itp = pBinding->begin( );
856 itp != pBinding->end( );
859 for (std::map<CoreferentAnnotation*, float>::iterator its = (*itp).second.begin( );
860 its != (*itp).second.end( );
869 if ((*npCandidates->begin()).find((*its).first) != (*npCandidates->begin()).end() && (*itp).first->morphVertex()>=(*its).first->morphVertex())
871 (*its).second += cataphoraWeight;
876 for (std::map< std::string,std::deque<std::string> >::const_iterator itDr =
m_relLocalDef.begin();
880 const std::deque<std::string> macroDependencyRel = (*itDr).second;
882 if ((*itp).first->isFunctionMasterOf(sd,macroDependencyRel,
m_language)
883 && (*its).first->isFunctionMasterOf(sd,macroDependencyRel,
m_language))
885 (*its).second += sameSlotWeight;
900 if ((*itp).first==(*its).first)
902 (*its).second += itselfWeight;
915 LDEBUG <<
"CorefSolver::applyCircularFilter binding size = " << pBinding->size();
917 bool crossReferenceFound =
false;
920 crossReferenceFound =
false;
921 for (WeightedVerticesRelation::iterator itp = pBinding->begin( ); itp != pBinding->end( );
924 CoreferentAnnotation* source = (*itp).first;
925 source->morphVertex();
926 for (std::map<CoreferentAnnotation*, float>::iterator its = (*itp).second.begin( ); its != (*itp).second.end( ); its++ )
928 CoreferentAnnotation* target = (*its).first;
930 if (source != target && pBinding->find(target) != pBinding->end())
933 LDEBUG <<
"Check cross reference between " << source->morphVertex() <<
" and " << target->morphVertex();
935 WeightedVerticesRelation::iterator targetIt = pBinding->find(target);
937 if ( (*targetIt).second.find(source) != (*targetIt).second.end() )
939 crossReferenceFound =
true;
940 float sourceToTargetWeight = (*its).second;
941 float targetToSourceWeight = (*(*targetIt).second.find(source)).second;
943 LDEBUG <<
"Cross reference found between " << source->morphVertex() <<
" ("<<sourceToTargetWeight<<
") and " << target->morphVertex() <<
" ("<<targetToSourceWeight<<
")";
946 if (sourceToTargetWeight >= targetToSourceWeight)
949 LDEBUG <<
" erasing " << (*targetIt).first->morphVertex() <<
" -> " << (*(*targetIt).second.find(source)).first->morphVertex();
951 (*targetIt).second.erase( (*targetIt).second.find(source) ) ;
957 LDEBUG <<
" erasing " << (*itp).first->morphVertex() <<
" -> " << (*its).first->morphVertex();
959 (*itp).second.erase(its);
966 if (crossReferenceFound)
break;
968 }
while (crossReferenceFound);
970 LDEBUG <<
"No more cross references";
980 for (WeightedVerticesRelation::iterator itp = pBinding->begin( );
981 itp != pBinding->end( );
984 for (std::map<CoreferentAnnotation*, float>::iterator its = (*itp).second.begin( );
985 its != (*itp).second.end( );
989 LDEBUG <<
" threshold bewteen " << (*itp).first->morphVertex() <<
" and " << (*its).first->morphVertex() <<
" ; value: " << (*its).second;
996 (*itp).second.erase(its);
998 its = (*itp).second.begin( );
1004void CorefSolver::applyMorphoSyntacticFilter(
1010 LDEBUG <<
"CorefSolver::applyMorphoSyntacticFilter binding size = " << pBinding->size();
1012 for (WeightedVerticesRelation::iterator itp = pBinding->begin( );
1013 itp != pBinding->end( );
1016 std::set<CoreferentAnnotation*> roSet = (*roBinding->find((*itp).first)).second;
1017 for (std::set<CoreferentAnnotation*>::iterator itro = roSet.begin( );
1018 itro != roSet.end( );
1022 LDEBUG <<
" erasing " << (*itp).first->morphVertex() <<
" -> " << (*itro)->morphVertex();
1024 (*itp).second.erase(*itro);
This file is the main header file for the data related to annotation graphs.
LinguisticGraph::vertex_descriptor LinguisticGraphVertex
LinguisticGraph::out_edge_iterator LinguisticGraphOutEdgeIt
boost::adjacency_list< boost::vecS, boost::vecS, boost::bidirectionalS, LinguisticVertexProperties > LinguisticGraph
Property to identify the chains in the graph.
#define COREFSOLVERLOGINIT
Defines a Factory to create Object of type Base.
Data used for the simplification of sentences allowing easier heterosyntagmatic analysis.
Data used for the syntactic analyzis of texts.
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 an annotation graph and gives an API to manipulate it.
Provide tools to manage a specific property.
const PropertyAccessor & getPropertyAccessor() const
give the corresponding PropertyAccessor
LinguisticCode getPropertyValue(const std::string &symbolicValue) const
Get the coded property value from the symbolic value.
std::string & getParamsValueAtKey(const std::string &key)
std::deque< std::string > & getListsValueAtKey(const std::string &key)
std::map< std::string, std::string > & getMapAtKey(const std::string &key)
return a message when a 'list' was not found
return a message when a 'map' was not found
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::set< LinguisticCode > m_inNpCategs
const Common::PropertyCode::PropertyAccessor * m_numberAccessor
const Common::PropertyCode::PropertyAccessor * m_macroAccessor
std::set< LinguisticCode > m_possPronouns
const Common::PropertyCode::PropertyAccessor * m_personAccessor
std::set< LinguisticCode > m_reflexiveReciprocal
std::map< std::string, float > m_salienceWeights
std::map< std::string, LinguisticCode > m_tagLocalDef
std::map< std::string, std::deque< std::string > > m_relLocalDef
void init(Common::XMLConfigurationFiles::GroupConfigurationStructure &unitConfiguration, Manager *manager) override
initialize with parameters from configuration file.
const Common::PropertyCode::PropertyAccessor * m_genderAccessor
LimaStatusCode process(AnalysisContent &analysis) const override
LinguisticCode m_conjCoord
const Common::PropertyCode::PropertyAccessor * m_microAccessor
bool m_resolveN3PPronouns
std::set< LinguisticCode > m_definiteCategs
std::map< std::string, int > m_slotValues
std::set< LinguisticCode > m_undefPronouns
std::map< CoreferentAnnotation *, std::set< CoreferentAnnotation * > > VerticesRelation
bool isIncludedInNounPhrase(const LinguisticGraph *g, MediaId language, const LinguisticAnalysisStructure::AnalysisGraph *anagraph, AnalysisContent &ac, const std::set< LinguisticCode > &inNpCategs, const Common::PropertyCode::PropertyAccessor *microAccessor) const
general test functions
std::map< CoreferentAnnotation *, std::map< CoreferentAnnotation *, float > > WeightedVerticesRelation
Definition of a function suitable to be used as a dumper for Coreferent Annotations of an Annotation ...
An AnalysisData containing a LinguisticGraph with a language and an id.
const LinguisticGraph * getGraph(void) const
Returns the underlying graph structure.
This constraint tests if its argument is the governor of a relation of the given type.
This constraint tests if the second argument is not governed by the first one with a relation of the ...
This class points to a graph, its dependency graph and the structure that holds the maping between th...
static const MediaticData & single()
const singleton accessor
static void logElapsedTime(const std::string &mess, const std::string &taskCategory=std::string(""))
log the number of microseconds since last UpdateCurrentTime
static void updateCurrentTime(const std::string &taskCategory=std::string(""))
store current time for new elapsed time computation
#define COREFSOLVINGPU_CLASSID
std::string limastring2utf8stdstring(const Lima::LimaString &phrase, uint32_t size0)
Convert a wide string to a string , in dest up to size bytes.
LimaString utf8stdstring2limastring(const std::string &src)
std::set< CoreferentAnnotation * > Vertices
std::map< CoreferentAnnotation *, std::set< CoreferentAnnotation * > > VerticesRelation
std::map< CoreferentAnnotation *, std::map< CoreferentAnnotation *, float > > WeightedVerticesRelation
SimpleFactory< MediaProcessUnit, CorefSolver > coreferencesSolvingProcessUnit(COREFSOLVINGPU_CLASSID)