package cz.brmlab.yodaqa.analysis.question;

import org.apache.uima.UimaContext;
import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
import org.apache.uima.fit.component.JCasAnnotator_ImplBase;
import org.apache.uima.fit.util.JCasUtil;
import org.apache.uima.jcas.JCas;
import org.apache.uima.jcas.tcas.Annotation;
import org.apache.uima.resource.ResourceInitializationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cz.brmlab.yodaqa.model.Question.Clue;

import de.tudarmstadt.ukp.dkpro.core.api.syntax.type.constituent.Constituent;
import de.tudarmstadt.ukp.dkpro.core.api.syntax.type.constituent.ROOT;
import de.tudarmstadt.ukp.dkpro.core.api.syntax.type.dependency.NSUBJ;

/**
 * Generate Clue annotations in a QuestionCAS. These represent key information
 * stored in the question that is then used in primary search.
 *
 * This generates clues from the question subject, i.e. NSUBJ annotation.
 * E.g. in "When did Einstein die?", subject is "Einstein" and will have such
 * a clue generated. */

public class ClueBySubject extends JCasAnnotator_ImplBase {
	final Logger logger = LoggerFactory.getLogger(ClueBySubject.class);

	public void initialize(UimaContext aContext) throws ResourceInitializationException {
		super.initialize(aContext);
	}

	public void process(JCas jcas) throws AnalysisEngineProcessException {
		for (ROOT sentence : JCasUtil.select(jcas, ROOT.class)) {
			processSentence(jcas, sentence);
		}
	}

	public void processSentence(JCas jcas, Constituent sentence) throws AnalysisEngineProcessException {
		for (NSUBJ subj : JCasUtil.selectCovered(NSUBJ.class, sentence)) {
			/* Skip question word focuses (e.g. "Who"). */
			if (subj.getDependent().getPos().getPosValue().matches("^W.*"))
				continue;
			addClue(jcas, subj.getBegin(), subj.getEnd(), subj);
		}
	}

	protected void addClue(JCas jcas, int begin, int end, Annotation base) {
		Clue clue = new Clue(jcas);
		clue.setBegin(begin);
		clue.setEnd(end);
		clue.setBase(base);
		clue.setWeight(2.5);
		clue.addToIndexes();
		logger.debug("new by {}: {}", base.getType().getShortName(), clue.getCoveredText());
	}
}

@@ -38,16 +38,40 @@
 stion;%0A%0A
+import java.util.List;%0A%0A
 import o
@@ -474,16 +474,59 @@
 ctory;%0A%0A
+import cz.brmlab.yodaqa.analysis.TreeUtil;%0A
 import c
@@ -563,16 +563,82 @@
 .Clue;%0A%0A
+import de.tudarmstadt.ukp.dkpro.core.api.segmentation.type.Token;%0A
 import d
@@ -1774,16 +1774,54 @@
 nce)) %7B%0A
+%09%09%09Token stok = subj.getDependent();%0A%0A
 %09%09%09/* Sk
@@ -1870,34 +1870,19 @@
 %09%09%09if (s
-ubj.getDependent()
+tok
 .getPos(
@@ -1932,63 +1932,569 @@
 ue;%0A
-%09%09%09addClue(jcas, subj.getBegin(), subj.getEnd(), subj);
+%0A%09%09%09/* If the subject governs an object, e.g.%0A%09%09%09 * %22Holmes' name%22 or %22capital of Argentina%22,%0A%09%09%09 * switch the subject to %22Holmes%22 and %22Argentina%22%0A%09%09%09 * and keep the original only with lower priority. */%0A%09%09%09List%3CToken%3E objDeps = TreeUtil.getAllGoverned(jcas, sentence, stok, %22pobj%7Cposs%22);%0A%09%09%09if (!objDeps.isEmpty()) %7B%0A%09%09%09%09for (Token objDep : objDeps)%0A%09%09%09%09%09addClue(jcas, objDep.getBegin(), objDep.getEnd(), objDep, 2.0);%0A%0A%09%09%09%09addClue(jcas, subj.getBegin(), subj.getEnd(), subj, 1.0);%0A%09%09%09%7D else %7B%0A%09%09%09%09addClue(jcas, subj.getBegin(), subj.getEnd(), subj, 2.5);%0A%09%09%09%7D
 %0A%09%09%7D
@@ -2568,16 +2568,31 @@
 ion base
+, double weight
 ) %7B%0A%09%09Cl
@@ -2700,19 +2700,22 @@
 tWeight(
-2.5
+weight
 );%0A%09%09clu

Prefer subject's dependents to the subject itself