41 const uint64_t maxCompoundSize=0,
42 const uint64_t nbMaxPartialCompounds=1000);
48 void getPositionLengthList(
const std::vector<uint64_t>& structure,
60 void storePartsInQueue(boost::shared_ptr< BoWToken > token);
62 bool addPartElementsInQueue(boost::shared_ptr< BoWToken > token,
63 std::pair<std::vector<uint64_t>, uint64_t> & ids_rels,
80 const std::vector<std::pair<std::vector<uint64_t>, uint64_t> >& partIds_Rels,
83 std::pair<std::vector<uint64_t>, uint64_t>& ids_rels,
84 std::vector<uint64_t>& structure,
85 std::vector<uint64_t>& relations,
88 typedef std::deque<IndexElement> IndexElementQueue;
91 BoWText::const_iterator m_iterator;
92 BoWText::const_iterator m_iteratorEnd;
93 IndexElementQueue m_partQueue;
94 uint64_t m_maxSizeQueue;
95 uint64_t m_maxCompoundSize;
97 QMap<QString,IndexElement> m_alreadyFoundElements;
100IndexElementIteratorPrivate::IndexElementIteratorPrivate(
const BoWText& bowText,
102 const uint64_t maxCompoundSize,
103 const uint64_t nbMaxPartialCompounds):
104m_iterator(bowText.begin()),
105m_iteratorEnd(bowText.end()),
107m_maxSizeQueue(nbMaxPartialCompounds),
108m_maxCompoundSize(maxCompoundSize),
109m_idGenerator(idGenerator)
111 if (m_idGenerator==0) {
115 if (m_maxCompoundSize==0) {
118 m_maxCompoundSize=UINT_MAX;
122IndexElementIteratorPrivate::IndexElementIteratorPrivate(
const IndexElementIteratorPrivate& ieip):
123m_iterator(ieip.m_iterator),
124m_iteratorEnd(ieip.m_iteratorEnd),
125m_partQueue(ieip.m_partQueue),
126m_maxSizeQueue(ieip.m_maxSizeQueue),
127m_maxCompoundSize(ieip.m_maxCompoundSize)
129 m_idGenerator=
new DefaultIdGenerator(
131 *m_idGenerator = *ieip.m_idGenerator;
134IndexElementIteratorPrivate::~IndexElementIteratorPrivate()
136 delete m_idGenerator;
144 const uint64_t maxCompoundSize,
145 const uint64_t nbMaxPartialCompounds):
164 return (m_d->m_iterator == m_d->m_iteratorEnd);
177 LDEBUG <<
"IndexElementIterator::getElement empty:" << m_d->m_partQueue.empty();
182 if (m_d->m_partQueue.empty())
184 if (m_d->m_iterator==m_d->m_iteratorEnd)
187 LDEBUG <<
"IndexElementIterator::getElement at end: return empty element";
193 boost::shared_ptr< BoWToken> token = boost::dynamic_pointer_cast<BoWToken>((*m_d->m_iterator));
194 boost::shared_ptr< BoWPredicate > predicate;
196 switch ((*m_d->m_iterator)->getType())
201 LDEBUG <<
"IndexElementIterator::getElement simple token:" << token->getIdUTF8String();
203 if (!m_d->m_alreadyFoundElements.contains(QString::fromUtf8(token->getIdUTF8String().c_str())))
205 m_d->m_alreadyFoundElements.insert(QString::fromUtf8(token->getIdUTF8String().c_str()),
209 token->getCategory(),
210 token->getPosition(),
214 return m_d->m_alreadyFoundElements[QString::fromUtf8(token->getIdUTF8String().c_str())];
218 LDEBUG <<
"IndexElementIterator::getElement term:" << token->getIdUTF8String();
220 m_d->storePartsInQueue(token);
221 if (m_d->m_partQueue.empty())
224 LDEBUG <<
"IndexElementIterator::getElement term: part queue is empty" ;
230 LDEBUG <<
"IndexElementIterator::getElement term after storePartsInQueue front is:" << m_d->m_partQueue.front();
232 m_d->m_alreadyFoundElements.insert(QString::fromUtf8(token->getIdUTF8String().c_str()),m_d->m_partQueue.front());
233 return m_d->m_partQueue.front();
237 LDEBUG <<
"IndexElementIterator::getElement named entity:" << boost::dynamic_pointer_cast<BoWNamedEntity>(*m_d->m_iterator)->getIdUTF8String() ;
240 m_d->storePartsInQueue(token);
242 LDEBUG <<
"IndexElementIterator::getElement ne after storePartsInQueue front is:" << m_d->m_partQueue.front();
244 if (m_d->m_partQueue.empty())
247 LDEBUG <<
"IndexElementIterator::getElement ne: part queue is empty" ;
252 m_d->m_alreadyFoundElements.insert(QString::fromUtf8(token->getIdUTF8String().c_str()),m_d->m_partQueue.front());
253 return m_d->m_partQueue.front();
258 predicate = boost::dynamic_pointer_cast<BoWPredicate>((*m_d->m_iterator));
259 uint64_t
id=m_d->m_idGenerator->
getId(predicate->getString());
261 predicate->getType(),
262 predicate->getString(),
264 predicate->getPosition(),
265 predicate->getLength(),
266 predicate->getPredicateType()
277 LDEBUG <<
"IndexElementIterator::getElement empty:" << m_d->m_partQueue.empty() <<
"return part queue front" << m_d->m_partQueue.front();
279 return m_d->m_partQueue.front();
296 if (m_d->m_partQueue.empty()) {
298 LDEBUG <<
"IndexElementIterator::operator++ part queue is empty";
300 if (m_d->m_iterator!=m_d->m_iteratorEnd) {
304 LDEBUG <<
"IndexElementIterator::operator++ Jump if necessary";
306 while (m_d->m_iterator != m_d->m_iteratorEnd &&
307 boost::dynamic_pointer_cast<BoWToken>((*m_d->m_iterator)) &&
308 m_d->m_alreadyFoundElements.contains( QString::fromUtf8(boost::dynamic_pointer_cast<BoWToken>((*m_d->m_iterator))->getIdUTF8String().c_str()) ) ) {
315 LDEBUG <<
"IndexElementIterator::operator++ part queue not empty";
317 m_d->m_partQueue.pop_front();
318 if (m_d->m_partQueue.empty()) {
321 while (m_d->m_iterator != m_d->m_iteratorEnd &&
322 boost::dynamic_pointer_cast<BoWToken>((*m_d->m_iterator)) &&
323 m_d->m_alreadyFoundElements.contains( QString::fromUtf8(boost::dynamic_pointer_cast<BoWToken>((*m_d->m_iterator))->getIdUTF8String().c_str()) ) ) {
341void IndexElementIteratorPrivate::getPositionLengthList(
const std::vector<uint64_t>& structure,
346 for (std::vector<uint64_t>::const_iterator it = structure.begin(); it != structure.end(); ++it) {
348 QMap<QString,IndexElement>::const_iterator found = m_alreadyFoundElements.begin();
349 while (found != m_alreadyFoundElements.end() && *it != found.value().getId()) {
353 if (found != m_alreadyFoundElements.end()) {
355 poslenlist.insert(poslenlist.end(), p.begin(), p.end());
359 LERROR <<
"getPositionLengthList failure: element id " << *it <<
" not found";
364 std::sort(poslenlist.begin(),poslenlist.end());
368bool IndexElementIteratorPrivate::addInPartQueue(
const IndexElement& newElement)
372 LDEBUG <<
"IndexElementIteratorPrivate::addInPartQueue" << newElement;
374 if (m_partQueue.size() >= m_maxSizeQueue) {
376 LWARN <<
"size of queue exceeded";
380 m_partQueue.push_back(newElement);
397void IndexElementIteratorPrivate::storePartsInQueue(boost::shared_ptr< Lima::Common::BagOfWords::BoWToken > token)
401 LDEBUG <<
"IndexElementIteratorPrivate::storePartsInQueue" << token->getIdUTF8String();
403 pair<vector<uint64_t>, uint64_t> tokenIds;
404 if (!addPartElementsInQueue(token,tokenIds,0)) {
406 LWARN <<
"Token contain too many subparts (some are ignored): " << token->getLemma();
410bool IndexElementIteratorPrivate::addPartElementsInQueue(boost::shared_ptr< BoWToken > token,
411 pair<vector<uint64_t>, uint64_t>& ids_rel,
416 LDEBUG <<
"IndexElementIteratorPrivate::addPartElementsInQueue" << token->getIdUTF8String() << rel;
421 switch (token->getType())
426 LDEBUG <<
"IndexElementIteratorPrivate::addPartElementsInQueue simple token:" << token->getIdUTF8String();
428 if (!m_alreadyFoundElements.contains(QString::fromUtf8(token->getIdUTF8String().c_str())))
431 if (lemma.size()==0) {
432 lemma=token->getInflectedForm();
435 uint64_t
id=m_idGenerator->
getId(token->getString());
437 m_alreadyFoundElements.insert(QString::fromUtf8(token->getIdUTF8String().c_str()),IndexElement(
id,
440 token->getCategory(),
441 token->getPosition(),
444 result = addInPartQueue(m_alreadyFoundElements[QString::fromUtf8(token->getIdUTF8String().c_str())]);
448 ids_rel=make_pair(vector<uint64_t>(1,m_alreadyFoundElements[QString::fromUtf8(token->getIdUTF8String().c_str())].getId()),rel);
452 neType=boost::dynamic_pointer_cast<BoWNamedEntity>(token)->getNamedEntityType();
461 boost::shared_ptr< BoWComplexToken > complexToken=
462 boost::dynamic_pointer_cast<BoWComplexToken>(token);
464 if (complexToken==0) {
466 LERROR <<
"failed to convert BoWText element in complex token";
470 if (complexToken->size() == 1) {
472 LDEBUG <<
"IndexElementIteratorPrivate::addPartElementsInQueue complex token of size one";
477 if (!m_alreadyFoundElements.contains(QString::fromUtf8(token->getIdUTF8String().c_str())))
479 uint64_t
id=m_idGenerator->
getId(token->getString());
480 ids_rel=make_pair(vector<uint64_t>(1,
id),rel);
483 if (lemma.size()==0) {
484 lemma=token->getInflectedForm();
486 m_alreadyFoundElements.insert(QString::fromUtf8(token->getIdUTF8String().c_str()), IndexElement(
id,
489 token->getCategory(),
490 token->getPosition(),
493 result = addInPartQueue(m_alreadyFoundElements[QString::fromUtf8(token->getIdUTF8String().c_str())]);
495 return result =
true;
501 LDEBUG <<
"IndexElementIteratorPrivate::addPartElementsInQueue complex token of size" << complexToken->size();
503 ids_rel=make_pair(vector<uint64_t>(),rel);
504 uint64_t nbParts=complexToken->getParts().size();
505 uint64_t head=complexToken->getHead();
506 vector<pair<vector<uint64_t>, uint64_t> > partIdsRels(nbParts);
507 for (uint64_t i=0; i<nbParts; i++) {
509 LDEBUG <<
"IndexElementIteratorPrivate::addPartElementsInQueue on part" << i <<
"of complex token" << *complexToken;
511 pair<vector<uint64_t>, uint64_t>& thisPartIdsRels=partIdsRels[i];
513 boost::shared_ptr< BoWRelation > relation=(complexToken->getParts()[i]).getBoWRelation();
514 if (relation !=0 ) relType=relation->getSynType();
else relType=0;
515 if (!addPartElementsInQueue(complexToken->getParts()[i].getBoWToken(),thisPartIdsRels,relType)) {
521 ids_rel.first.insert(ids_rel.first.end(),thisPartIdsRels.first.begin(),thisPartIdsRels.first.end());
525 LDEBUG <<
"IndexElementIteratorPrivate::addPartElementsInQueue parts added; combining them";
528 vector<uint64_t> structure;
529 vector<uint64_t> relations;
530 if (!addCombinedPartsInQueue(token->getType(),partIdsRels,head,neType,ids_rel,structure,relations,0)) {
536bool IndexElementIteratorPrivate::addCombinedPartsInQueue(
538 const std::vector<std::pair<std::vector<uint64_t>, uint64_t> >& partIdsRels,
541 std::pair<std::vector<uint64_t>, uint64_t>& ids_rel,
542 std::vector<uint64_t>& structure,
543 std::vector<uint64_t>& relations,
544 const uint64_t current)
549 QStringList structureKey;
550 for (
auto it = structure.begin(); it != structure.end(); ++it) {
551 structureKey << QString::number(*it);
554 LDEBUG <<
"addCombinedPartsInQueue: nb parts=" << partIdsRels.size()
555 <<
", head=" << head <<
", current=" << current <<
", structure=" << structureKey.join(
";");
558 if (current>=partIdsRels.size()) {
559 if (structure.size() == 1) {
562 LDEBUG <<
"addCombinedPartsInQueue: just the head: is already in queue";
570 if (!m_alreadyFoundElements.contains(structureKey.join(
";")))
572 IndexElement compoundElement(0,type,structure,relations,neType);
573 getPositionLengthList(structure,compoundElement.getPositionLengthList());
574 if (compoundElement.getPositionLengthList().size() > m_maxCompoundSize) {
578 LDEBUG <<
"addCombinedPartsInQueue: just the head: max compound size exceeded";
584 uint64_t
id=m_idGenerator->
getId(structure);
586 LDEBUG <<
"IndexElementIterator: got id from generator " << id;
588 compoundElement.setId(
id);
589 m_alreadyFoundElements.insert(structureKey.join(
";"),compoundElement);
590 if (!addInPartQueue(m_alreadyFoundElements[structureKey.join(
";")])) {
592 LDEBUG <<
"addCombinedPartsInQueue: queue overflow";
601 ids_rel.first.push_back(m_alreadyFoundElements[structureKey.join(
";")].getId());
603 LDEBUG <<
"addCombinedPartsInQueue: added to ids_rel.first: " << m_alreadyFoundElements[structureKey.join(
";")].getId() <<
"; return" << result;
609 for (
auto it = partIdsRels[current].first.begin(); it != partIdsRels[current].first.end(); ++it) {
610 structure.push_back(*it);
611 relations.push_back(partIdsRels[current].second);
612 if (!addCombinedPartsInQueue(type, partIdsRels,head,neType,ids_rel,structure,relations,current+1)) {
614 LDEBUG <<
"addCombinedPartsInQueue: recursive call returned false";
618 structure.pop_back();
619 relations.pop_back();
625 if (!addCombinedPartsInQueue(type, partIdsRels,head,neType,ids_rel,structure,relations,current+1)) {
627 LDEBUG <<
"addCombinedPartsInQueue: second recursive call returned false";
virtual uint64_t getId(const LimaString &word) override=0
This class represents a list of elements, that are pointers on polymmorphic tokens that can be simple...
An iterator on the bowText that returns IndexElements.
const IndexElement & getElement() const
IndexElementIterator(const BoWText &bowText, AbstractLexiconIdGenerator *idAccessor=0, const uint64_t maxCompoundSize=0, const uint64_t nbMaxPartialCompounds=1000)
constructor
IndexElementIterator & operator++()
Represent an element of an index If it is a predicate, its simple term is "PredicateElement" and its ...
BoWType
enum to characterize the type of the AbstractBoWElement
@ BOW_NOTYPE
the AbstractBoWElement is an abstract one that should not be instanciated
@ BOW_TERM
the AbstractBoWElement is a multi-term
@ BOW_NAMEDENTITY
the AbstractBoWElement is a named entity
@ BOW_TOKEN
the AbstractBoWElement is a simple token
@ BOW_PREDICATE
the AbstractBoWElement is a predicate (n-ary relation, template or semantic frame
std::vector< std::pair< Position, Length > > PositionLengthList