src/Generic/actors/ActorMentionFinder.cpp
/* Does not include software, that has a separate function createSoftwareMention */
Does not include software, that has a separate function createSoftwareMention
Does not include software that has a separate function createSoftwareMention
ActorMention_ptr ActorMentionFinder::createProperNounActorMention(
	const ActorMatch &match, const SentenceTheory *sentTheory, Symbol sourceNote,
	bool &head_match, bool &country_the_plural) 
{
	const Mention *mention = getCoveringNameDescMention(sentTheory, match.start_token, match.end_token);
	head_match = (mention != 0);
	if (!head_match) {
		const SynNode *parseRoot = sentTheory->getPrimaryParse()->getRoot();
		const SynNode *coveringNode = parseRoot->getCoveringNodeFromTokenSpan(match.start_token, match.end_token);
		if (coveringNode->getParent() && coveringNode->getParent()->getParent() && 
			(coveringNode->getParent()->getParent()->getTag() == NPP_SYM)) {
			coveringNode = coveringNode->getParent()->getParent();
			mention = getCoveringNameDescMention(sentTheory, coveringNode);
			if (mention && (_verbosity > 4)) {
				SessionLogger::info("ICEWS") << "    Non-head match: mention = ["
					<< mention->toCasedTextString() << "].  pattern match = ["
					<< sentTheory->getTokenSequence()->toString(match.start_token, match.end_token) 
					<< "], head = [" << coveringNode->getHead()->toCasedTextString(sentTheory->getTokenSequence()) << "]";
			}
		}
	}
	if (!mention)
		return ActorMention_ptr();
	if (_only_match_names && mention->getMentionType() != Mention::NAME) {
		return ActorMention_ptr();
	}
	const SynNode *node = mention->getAtomicHead();
	bool same_start_tok = (node->getStartToken() == match.start_token);
	bool same_end_tok = (node->getEndToken() == match.end_token);
	bool actor_is_a_country = _actorInfo->isACountry(match.id);
	bool actor_is_an_individual = _actorInfo->isAnIndividual(match.id);
	bool actor_is_an_org = !(actor_is_a_country || actor_is_an_individual);
	country_the_plural = false;
	if (actor_is_a_country && mention->getMentionType() == Mention::DESC &&
		node->getTag() == Symbol(L"NNPS") && node->getParent() != 0 && node->getParent()->getTag() == Symbol(L"NPP"))
	{
		const SynNode* parent = node->getParent()->getParent();
		if (parent != 0 && parent->getParent() != 0 && parent->getParent()->hasMention() &&
			sentTheory->getMentionSet()->getMention(parent->getParent()->getMentionIndex())->getMentionType() == Mention::DESC) 
		{
		} else if (parent != 0 && parent->getStartToken() + 1 == parent->getEndToken() && parent->getNthTerminal(0)->getHeadWord() == Symbol(L"the"))	{
			country_the_plural = true;
		}
	}
	if (!(same_start_tok && same_end_tok) && !country_the_plural) {
		const std::set<std::wstring> & modifierWords = (actor_is_a_country ?     _countryModifierWords : 
		                                                actor_is_an_individual ? _personModifierWords : 
		                                                                         _organizationModifierWords);
		const char* context = actor_is_a_country ? "a country" : (actor_is_an_individual ? "a person" : "an organization");
		int start_tok = node->getStartToken();
		int end_tok = node->getEndToken();
		for (int tok=start_tok; tok<=end_tok; ++tok) {
			if ((tok<match.start_token) || (tok>match.end_token)) {
				const SynNode *preterminal = node->getNthTerminal(tok-start_tok)->getParent();
				Symbol postag = preterminal ? preterminal->getTag() : Symbol(L"???");
				if ((!actor_is_a_country) && (postag == JJ_POS_SYM)) continue;
				std::wstring tokStr(sentTheory->getTokenSequence()->getToken(tok)->getSymbol().to_string());
				boost::to_lower(tokStr);
				if ((tokStr == L"north" && node->getHeadWord() == Symbol(L"korea")) ||
					 modifierWords.find(tokStr) == modifierWords.end())
				{
					if (_verbosity > 3) {
						SessionLogger::info("ICEWS") << "    Skipping mention \"" << mention->toCasedTextString() 
							<< "\" which matches pattern \""
							<< sentTheory->getTokenSequence()->toString(match.start_token, match.end_token) << "\" "
							<< "(head=\"" << node->toCasedTextString(sentTheory->getTokenSequence()) << "\") "
							<< "because the actor is " << context << ", and the mention contains the unexpected word \""
							<< tokStr << "\" (" << postag << ")" << std::endl;
					}
					return ActorMention_ptr(); 
				}
			}
		}
	}
	ActorMention_ptr actorMention;
	if (match.code == BLOCK_ACTOR_SYM) {
		actorMention = boost::make_shared<ActorMention>(sentTheory, mention, BLOCK_ACTOR_SYM);
	} else {
		actorMention = boost::make_shared<ProperNounActorMention>(sentTheory, mention, sourceNote,
			ActorMention::ActorIdentifiers(match, _actorInfo->getActorName(match.id), _actorTokenMatcher->patternRequiresContext(match.patternId)));
	}
	if (!same_end_tok)
		actorMention->addSourceNote(PATTERN_END_IS_NOT_MENTION_END_SYM);
	if (_require_entity_type_match) {
		if (ProperNounActorMention_ptr pn_actor = boost::dynamic_pointer_cast<ProperNounActorMention>(actorMention)) {
			if (!entityTypeMatches(pn_actor, mention->getEntityType())) {
				return ActorMention_ptr();
			}
		}
	}
	return actorMention;
}
ActorMention_ptr ActorMentionFinder :: createProperNounActorMention ( const ActorMatch & match , const SentenceTheory * sentTheory , Symbol sourceNote , bool & head_match , bool & country_the_plural ) { const Mention * mention = getCoveringNameDescMention ( sentTheory , match . start_token , match . end_token ) ; head_match = ( mention != 0 ) ; if ( ! head_match ) { const SynNode * parseRoot = sentTheory -> getPrimaryParse ( ) -> getRoot ( ) ; const SynNode * coveringNode = parseRoot -> getCoveringNodeFromTokenSpan ( match . start_token , match . end_token ) ; if ( coveringNode -> getParent ( ) && coveringNode -> getParent ( ) -> getParent ( ) && ( coveringNode -> getParent ( ) -> getParent ( ) -> getTag ( ) == NPP_SYM ) ) { coveringNode = coveringNode -> getParent ( ) -> getParent ( ) ; mention = getCoveringNameDescMention ( sentTheory , coveringNode ) ; if ( mention && ( _verbosity > 4 ) ) { SessionLogger :: info ( " " ) << " " << mention -> toCasedTextString ( ) << " " << sentTheory -> getTokenSequence ( ) -> toString ( match . start_token , match . end_token ) << " " << coveringNode -> getHead ( ) -> toCasedTextString ( sentTheory -> getTokenSequence ( ) ) << " " ; } } } if ( ! mention ) return ActorMention_ptr ( ) ; if ( _only_match_names && mention -> getMentionType ( ) != Mention :: NAME ) { return ActorMention_ptr ( ) ; } const SynNode * node = mention -> getAtomicHead ( ) ; bool same_start_tok = ( node -> getStartToken ( ) == match . start_token ) ; bool same_end_tok = ( node -> getEndToken ( ) == match . end_token ) ; bool actor_is_a_country = _actorInfo -> isACountry ( match . id ) ; bool actor_is_an_individual = _actorInfo -> isAnIndividual ( match . id ) ; bool actor_is_an_org = ! ( actor_is_a_country || actor_is_an_individual ) ; country_the_plural = false ; if ( actor_is_a_country && mention -> getMentionType ( ) == Mention :: DESC && node -> getTag ( ) == Symbol ( L" " ) && node -> getParent ( ) != 0 && node -> getParent ( ) -> getTag ( ) == Symbol ( L" " ) ) { const SynNode * parent = node -> getParent ( ) -> getParent ( ) ; if ( parent != 0 && parent -> getParent ( ) != 0 && parent -> getParent ( ) -> hasMention ( ) && sentTheory -> getMentionSet ( ) -> getMention ( parent -> getParent ( ) -> getMentionIndex ( ) ) -> getMentionType ( ) == Mention :: DESC ) { } else if ( parent != 0 && parent -> getStartToken ( ) + 1 == parent -> getEndToken ( ) && parent -> getNthTerminal ( 0 ) -> getHeadWord ( ) == Symbol ( L" " ) ) { country_the_plural = true ; } } if ( ! ( same_start_tok && same_end_tok ) && ! country_the_plural ) { const std :: set < std :: wstring > & modifierWords = ( actor_is_a_country ? _countryModifierWords : actor_is_an_individual ? _personModifierWords : _organizationModifierWords ) ; const char * context = actor_is_a_country ? " " : ( actor_is_an_individual ? " " : " " ) ; int start_tok = node -> getStartToken ( ) ; int end_tok = node -> getEndToken ( ) ; for ( int tok = start_tok ; tok <= end_tok ; ++ tok ) { if ( ( tok < match . start_token ) || ( tok > match . end_token ) ) { const SynNode * preterminal = node -> getNthTerminal ( tok - start_tok ) -> getParent ( ) ; Symbol postag = preterminal ? preterminal -> getTag ( ) : Symbol ( L" " ) ; if ( ( ! actor_is_a_country ) && ( postag == JJ_POS_SYM ) ) continue ; std :: wstring tokStr ( sentTheory -> getTokenSequence ( ) -> getToken ( tok ) -> getSymbol ( ) . to_string ( ) ) ; boost :: to_lower ( tokStr ) ; if ( ( tokStr == L" " && node -> getHeadWord ( ) == Symbol ( L" " ) ) || modifierWords . find ( tokStr ) == modifierWords . end ( ) ) { if ( _verbosity > 3 ) { SessionLogger :: info ( " " ) << " \" " << mention -> toCasedTextString ( ) << " \" \" " << sentTheory -> getTokenSequence ( ) -> toString ( match . start_token , match . end_token ) << " \" " << " \" " << node -> toCasedTextString ( sentTheory -> getTokenSequence ( ) ) << " \" " << " " << context << " \" " << tokStr << " \" " << postag << " " << std :: endl ; } return ActorMention_ptr ( ) ; } } } } ActorMention_ptr actorMention ; if ( match . code == BLOCK_ACTOR_SYM ) { actorMention = boost :: make_shared < ActorMention > ( sentTheory , mention , BLOCK_ACTOR_SYM ) ; } else { actorMention = boost :: make_shared < ProperNounActorMention > ( sentTheory , mention , sourceNote , ActorMention :: ActorIdentifiers ( match , _actorInfo -> getActorName ( match . id ) , _actorTokenMatcher -> patternRequiresContext ( match . patternId ) ) ) ; } if ( ! same_end_tok ) actorMention -> addSourceNote ( PATTERN_END_IS_NOT_MENTION_END_SYM ) ; if ( _require_entity_type_match ) { if ( ProperNounActorMention_ptr pn_actor = boost :: dynamic_pointer_cast < ProperNounActorMention > ( actorMention ) ) { if ( ! entityTypeMatches ( pn_actor , mention -> getEntityType ( ) ) ) { return ActorMention_ptr ( ) ; } } } return actorMention ; }
Does not include software, that has a separate function createSoftwareMention
Does not include software that has a separate function createSoftwareMention
// If the matched phrase isn't the head of a mention, see if it's a non-head
 // child of one.  This can occur for mis-parses, and in a few other cases.
 // If no such mention is found, then give up.
 // This is currently only set when matching using an AWAKE database
 // When matching country names, require that the name be exact (modulo some 
 // acceptable modifiers such as "western")
 // Look for things like "The Americans"
 // this is part of a bigger mention, let's bail
 // For people and orgs (but not countries), adjectives are acceptable.
 // Otherwise, the word must appear in our modifier words list.
 // Special case required to not allow "NORTH KOREA" to match "KOREA"
 // supress this match.
 // Construct a proper noun actor mention that links the 
 // actor mention from match with the entity mention.
 // If we're explicitly blocking this agent, then return an empty 
 // ActorMention; this will be discarded at the end of processing.
 // This is currently only set when matching using an AWAKE database
