Added and updated relation tests.
diff --git a/src/main/java/de/ids_mannheim/korap/query/SpanRelationMatchQuery.java b/src/main/java/de/ids_mannheim/korap/query/SpanRelationMatchQuery.java
index e0b8dd6..131c4ec 100644
--- a/src/main/java/de/ids_mannheim/korap/query/SpanRelationMatchQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/query/SpanRelationMatchQuery.java
@@ -42,21 +42,27 @@
checkVariables(relation, source, target);
SpanFocusQuery sq = null;
- // match source
+ SpanFocusQuery sq2 = null;
+ // match source and then target
if (relationQuery.getDirection() == 0) {
sq = new SpanFocusQuery(new SpanSegmentQuery(relationQuery,
operandQuery, true), relation.getTempTargetNum());
+ sq.setSorted(false);
+ sq.setMatchTemporaryClass(true);
+
+ sq2 = new SpanFocusQuery(new SpanSegmentQuery(operand2Query, sq,
+ true), relation.getTempClassNumbers());
}
- // match target
+ // match target and then source
else {
sq = new SpanFocusQuery(new SpanSegmentQuery(relationQuery,
operandQuery, true), relation.getTempSourceNum());
+ sq.setMatchTemporaryClass(true);
+
+ sq2 = new SpanFocusQuery(new SpanSegmentQuery(sq,
+ operand2Query, true), relation.getTempClassNumbers());
}
- sq.setSorted(false);
- sq.setMatchTemporaryClass(true);
-
- SpanFocusQuery sq2 = new SpanFocusQuery(new SpanSegmentQuery(sq,
- operand2Query, true), relation.getTempClassNumbers());
+
sq2.setMatchTemporaryClass(true);
sq2.setRemoveTemporaryClasses(true);
sq2.setSorted(false);
@@ -85,8 +91,7 @@
this.operandQuery = operand;
}
-
- public void checkVariables (SpanRelationQuery relation, SpanQuery operand,
+ public void checkVariables(SpanRelationQuery relation, SpanQuery operand,
SpanQuery target) {
checkVariables(relation, operand);
if (target == null) {
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/FocusSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/FocusSpans.java
index 25d1f76..244c79d 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/FocusSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/FocusSpans.java
@@ -173,10 +173,11 @@
// }
if (spanId > 0) hasSpanId = true;
}
- else if (cs.getSpanId() > 0) {
- hasSpanId = true;
- setSpanId(cs.getSpanId());
+ else if (cs.getSpanId() > 0) {
+ setSpanId(cs.getSpanId());
+ hasSpanId = true;
}
+
}
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/NextSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/NextSpans.java
index 34045fb..3db12a7 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/NextSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/NextSpans.java
@@ -82,6 +82,7 @@
matchDocNumber = firstSpans.doc();
matchStartPosition = firstSpans.start();
matchEndPosition = matchList.get(0).getEnd();
+ spanId = matchList.get(0).getSpanId();
if (collectPayloads)
matchPayload.addAll(matchList.get(0).getPayloads());
matchList.remove(0);
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/SegmentSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/SegmentSpans.java
index 46e4b28..d6b5d12 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/SegmentSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/SegmentSpans.java
@@ -92,19 +92,16 @@
*
* */
protected int findMatch () {
- RelationSpans s1;
- SimpleSpans s2;
-
if (firstSpans.start() == secondSpans.start()
&& firstSpans.end() == secondSpans.end()) {
if (isRelation) {
- s1 = (RelationSpans) firstSpans;
- s2 = (SimpleSpans) secondSpans;
+ RelationSpans s1 = (RelationSpans) firstSpans;
+ SimpleSpans s2 = (SimpleSpans) secondSpans;
if (s2.hasSpanId) {
if (s1.getLeftId() == s2.getSpanId()) {
- setSpanId(s2.getSpanId());
+ // setSpanId(s2.getSpanId());
setMatch();
return 0;
}
@@ -115,6 +112,22 @@
}
}
+ else if (firstSpans instanceof FocusSpans
+ && secondSpans instanceof SimpleSpans) {
+ SimpleSpans s1 = (SimpleSpans) firstSpans;
+ SimpleSpans s2 = (SimpleSpans) secondSpans;
+
+ if (s1.hasSpanId && s2.hasSpanId) {
+ if (s1.getSpanId() == s2.getSpanId()) {
+ setSpanId(s2.getSpanId());
+ hasSpanId = true;
+ }
+ }
+ else {
+ setMatch();
+ return 0;
+ }
+ }
else {
setMatch();
return 0;
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/SpansWithAttribute.java b/src/main/java/de/ids_mannheim/korap/query/spans/SpansWithAttribute.java
index af73f1f..30e57ef 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/SpansWithAttribute.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/SpansWithAttribute.java
@@ -180,6 +180,9 @@
this.matchEndPosition = referentSpans.end();
this.matchPayload = referentSpans.getPayload();
this.spanId = referentSpans.getSpanId();
+ if (this.spanId > 0) {
+ hasSpanId = true;
+ }
hasMoreSpans = referentSpans.next();
return true;
}
@@ -418,7 +421,12 @@
for (AttributeSpans as : notAttributeList) {
cost += as.cost();
}
- return referentSpans.cost() + cost;
+
+ if (referentSpans != null)
+ return referentSpans.cost() + cost;
+ else
+ return cost;
+
}
}
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestReferenceIndex.java b/src/test/java/de/ids_mannheim/korap/index/TestReferenceIndex.java
index 73d77f5..f1aeb02 100644
--- a/src/test/java/de/ids_mannheim/korap/index/TestReferenceIndex.java
+++ b/src/test/java/de/ids_mannheim/korap/index/TestReferenceIndex.java
@@ -72,13 +72,13 @@
kr = ki.search(ref, (short) 10);
/*
- for (Match km : kr.getMatches()) {
+ * for (Match km : kr.getMatches()) {
+ *
+ * System.out.println(km.getStartPos() + "," + km.getEndPos()
+ * + " " + km.getSnippetBrackets()); }
+ * System.out.println(kr.getTotalResults());
+ */
- System.out.println(km.getStartPos() + "," + km.getEndPos() + " "
- + km.getSnippetBrackets());
- }
- System.out.println(kr.getTotalResults());
- */
assertEquals(
"spanReference(spanDistance(focus(1: focus(#[1,2]spanSegment("
+ "focus(#1: spanSegment(spanRelation(base:<:child-of), focus(2: spanNext("
@@ -103,12 +103,12 @@
// .{0,2} #3 & #3 -> #2
assertEquals(
- "spanReference(focus(#[1,2]spanSegment(focus(#2: "
+ "spanReference(focus(#[1,2]spanSegment({2: <tokens:prp />}, focus(#2: "
+ "spanSegment(spanRelation(tokens:>:stanford/d:tag), "
+ "focus(3: spanDistance(focus(1: spanDistance({1: <tokens:vb />}, "
+ "{2: <tokens:prp />}, [(w[1:2], notOrdered, notExcluded)])), "
- + "{3: <tokens:nn />}, [(w[1:3], notOrdered, notExcluded)])))), "
- + "{2: <tokens:prp />})), 2)", sq.toString());
+ + "{3: <tokens:nn />}, [(w[1:3], notOrdered, notExcluded)]))))"
+ + ")), 2)", sq.toString());
SpanElementQuery seq1 = new SpanElementQuery("tokens", "vb");
// new SpanTermQuery(new Term("tokens", "c:vb"));
@@ -195,11 +195,13 @@
// #3 & #3 ->stanford/d #2 & #1 ->stanford #3' annis
// without layer=c and + relation key
assertEquals(
- "spanReference(focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(tokens:>:stanford/d:tag), "
- + "focus(1: spanReference(focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(tokens:>:stanford/d:tag), "
- + "focus(3: spanDistance(focus(1: spanDistance({1: <tokens:vb />}, {2: <tokens:prp />}, "
- + "[(w[1:2], notOrdered, notExcluded)])), {3: <tokens:nn />}, [(w[1:3], notOrdered, notExcluded)])))), "
- + "{2: <tokens:prp />})), 2)))), {3: <tokens:nn />})), 3)",
+ "spanReference(focus(#[1,2]spanSegment({3: <tokens:nn />}, "
+ + "focus(#2: spanSegment(spanRelation(tokens:>:stanford/d:tag), "
+ + "focus(1: spanReference(focus(#[1,2]spanSegment({2: <tokens:prp />}, "
+ + "focus(#2: spanSegment(spanRelation(tokens:>:stanford/d:tag), "
+ + "focus(3: spanDistance(focus(1: spanDistance({1: <tokens:vb />}, "
+ + "{2: <tokens:prp />}, [(w[1:2], notOrdered, notExcluded)])), "
+ + "{3: <tokens:nn />}, [(w[1:3], notOrdered, notExcluded)])))))), 2)))))), 3)",
sq.toString());
kr = ki.search(sq, (short) 10);
// for (Match km : kr.getMatches()) {
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestRelationIndex.java b/src/test/java/de/ids_mannheim/korap/index/TestRelationIndex.java
index b477cce..2c4ca89 100644
--- a/src/test/java/de/ids_mannheim/korap/index/TestRelationIndex.java
+++ b/src/test/java/de/ids_mannheim/korap/index/TestRelationIndex.java
@@ -17,6 +17,7 @@
import de.ids_mannheim.korap.query.SpanFocusQuery;
import de.ids_mannheim.korap.query.SpanRelationMatchQuery;
import de.ids_mannheim.korap.query.SpanRelationQuery;
+import de.ids_mannheim.korap.query.SpanSegmentQuery;
import de.ids_mannheim.korap.query.SpanTermWithIdQuery;
import de.ids_mannheim.korap.query.SpanWithAttributeQuery;
import de.ids_mannheim.korap.response.Match;
@@ -138,7 +139,7 @@
+ "<:child-of$<b>35<i>0<i>38<i>4<i>9<i>7<i>1<i>7<s>2<s>2<s>0|"
+ "<:dep$<b>32<i>0<s>1<s>1<s>0|"
+ "@:func=sbj$<b>18<i>7<s>4|" // attribute belongs to a relation
- + "@:case=nominative$<b>18<i>4<s>3]" // attribute belongs to a relation node
+ + "@:case=nominative$<b>18<i>1<s>3]" // attribute belongs to a relation node
+ "[(1-2)s:kaufe|_1$<i>4<i>9|pos:V$<s>1|<>:vp$<b>64<i>4<i>38<i>7<b>0<s>2|"
+ ">:child-of$<b>35<i>4<i>38<i>0<i>38<i>7<i>0<i>7<s>2<s>2<s>0|"
@@ -146,12 +147,14 @@
+ "<:child-of$<b>34<i>4<i>38<i>7<i>2<s>2<s>1<s>0|"
+ "<:child-of$<b>35<i>4<i>38<i>10<i>38<i>7<i>2<i>7<s>2<s>4<s>0|"
+ ">:dep$<b>32<i>0<s>1<s>1<s>0|"
- + ">:dep$<b>32<i>3<s>1<s>1<s>0]"
+ + ">:dep$<b>32<i>3<s>1<s>1<s>0]"
+ "[(2-3)s:die|_2$<i>10<i>13|pos:ART$<s>1|tt:DET$<s>2|"
+ "<>:np$<b>64<i>10<i>20<i>4<b>0<s>3|<>:np$<b>64<i>10<i>38<i>7<b>0<s>4|"
+ ">:child-of$<b>35<i>10<i>24<i>10<i>38<i>4<i>2<i>7<s>3<s>4<s>0|"
+
+ ">:child-of$<b>33<i>10<i>24<i>2<i>4<s>1<s>3<s>0|"
+
+ ">:child-of$<b>35<i>10<i>38<i>4<i>38<i>7<i>1<i>7<s>4<s>2<s>0|"
+ "<:child-of$<b>34<i>10<i>24<i>4<i>2<s>3<s>1<s>0|"
+ "<:child-of$<b>34<i>10<i>24<i>4<i>3<s>3<s>1<s>0|"
@@ -160,7 +163,8 @@
+ ">:parent-of$<b>35<i>10<i>38<i>21<i>38<i>7<i>4<i>7<s>4<s>2<s>0|"
+ "<:dep$<b>32<i>3<s>1<s>1<s>3|"
+ "@:func=head$<b>18<i>4<s>3|"
- + "@:case=accusative$<b>18<i>4<s>3]" // attribute belongs to a relation node
+ + "@:case=accusative$<b>18<i>4<s>3|" // attribute belongs to a relation node
+ + "@:case=accusative$<b>18<i>7<s>2]" // attribute belongs to a relation node
+ "[(3-4)s:Blümen|_3$<i>14<i>20|pos:NN$<s>1|"
+ ">:child-of$<b>33<i>10<i>24<i>2<i>4<s>1<s>3<s>0|"
@@ -178,7 +182,9 @@
+ ">:dep$<b>32<i>6<s>1<s>1<s>0]"
+ "[(5-6)s:meine|_5$<i>25<i>30|pos:ART$<s>1|<>:np$<b>64<i>25<i>38<i>7<b>0<s>2|"
+
+ ">:child-of$<b>33<i>25<i>38<i>5<i>7<s>1<s>2<s>0|"
+
+ ">:child-of$<b>35<i>25<i>38<i>21<i>38<i>7<i>4<i>7<s>2<s>2<s>0|"
+ "<:child-of$<b>34<i>25<i>38<i>7<i>5<s>2<s>1<s>0|"
+ "<:child-of$<b>34<i>25<i>38<i>7<i>6<s>2<s>1<s>0|"
@@ -580,23 +586,123 @@
assertEquals(6, kr.getMatch(5).getEndPos());
assertEquals(6, kr.getMatch(6).getStartPos());
assertEquals(7, kr.getMatch(6).getEndPos());
+ }
- // return all children of np that are articles
+ @Test
+ public void testCase9b() throws IOException {
+ ki.addDoc(createFieldDoc2());
+ ki.commit();
SpanTermWithIdQuery tiq = new SpanTermWithIdQuery(new Term("base",
"pos:ART"), true);
- SpanClassQuery scq2 = new SpanClassQuery(tiq, (byte) 2);
+ SpanClassQuery scq1 = new SpanClassQuery(tiq, (byte) 1);
+ SpanElementQuery seq = new SpanElementQuery("base", "np");
+ SpanClassQuery scq2 = new SpanClassQuery(seq, (byte) 2);
- srq = new SpanRelationQuery(new SpanTermQuery(new Term("base",
- ">:child-of")), true);
- rm = new SpanRelationMatchQuery(srq, scq2, scq1, true);
- rv = new SpanFocusQuery(rm, (byte) 2);
+ SpanRelationQuery srq = new SpanRelationQuery(new SpanTermQuery(
+ new Term("base", ">:child-of")), true);
+ srq.setSourceClass((byte) 1);
+ srq.setTargetClass((byte) 2);
- assertEquals(
- "focus(2: focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(base:>:child-of), {2: spanTermWithId(base:pos:ART)})), {1: <base:np />})))",
- rv.toString());
+ SpanRelationMatchQuery rm = new SpanRelationMatchQuery(srq, scq1, scq2,
+ true);
+
+ // return all nps whose children are articles
+ SpanFocusQuery rv = new SpanFocusQuery(rm, (byte) 2);
+ rv.setSorted(false);
kr = ki.search(rv, (short) 10);
+ assertEquals((long) 2, kr.getTotalResults());
+ assertEquals(2, kr.getMatch(0).getStartPos());
+ assertEquals(4, kr.getMatch(0).getEndPos());
+ assertEquals(5, kr.getMatch(1).getStartPos());
+ assertEquals(7, kr.getMatch(1).getEndPos());
+
+ // for (Match m : kr.getMatches()) {
+ // System.out.println(m.getStartPos() + " " + m.getEndPos());
+ // }
+ }
+
+ @Test
+ public void testCase9c() throws IOException {
+ ki.addDoc(createFieldDoc2());
+ ki.commit();
+
+ SpanTermWithIdQuery tiq = new SpanTermWithIdQuery(new Term("base",
+ "pos:ART"), true);
+ SpanClassQuery scq1 = new SpanClassQuery(tiq, (byte) 1);
+
+ kr = ki.search(scq1, (short) 10);
+ assertEquals((long) 2, kr.getTotalResults());
+ assertEquals(2, kr.getMatch(0).getStartPos());
+ assertEquals(3, kr.getMatch(0).getEndPos());
+ assertEquals(5, kr.getMatch(1).getStartPos());
+ assertEquals(6, kr.getMatch(1).getEndPos());
+
+ SpanRelationQuery srq = new SpanRelationQuery(new SpanTermQuery(
+ new Term("base", ">:child-of")), true);
+ srq.setSourceClass((byte) 1);
+ srq.setTargetClass((byte) 2);
+
+ // match articles as relation sources (left side)
+ SpanSegmentQuery ssq1 = new SpanSegmentQuery(srq, scq1);
+ // NOTE: SegmentSpans can only always adopt the relation left
+ // side id.
+
+ kr = ki.search(ssq1, (short) 10);
+ assertEquals(2, kr.getMatch(0).getStartPos());
+ assertEquals(3, kr.getMatch(0).getEndPos());
+ assertEquals(5, kr.getMatch(1).getStartPos());
+ assertEquals(6, kr.getMatch(1).getEndPos());
+
+ // return all parents of articles
+ SpanFocusQuery sfq = new SpanFocusQuery(ssq1, (byte) 2);
+ sfq.setSorted(false);
+
+ kr = ki.search(sfq, (short) 10);
+ assertEquals((long) 2, kr.getTotalResults());
+ assertEquals(2, kr.getMatch(0).getStartPos());
+ assertEquals(4, kr.getMatch(0).getEndPos());
+ assertEquals(5, kr.getMatch(1).getStartPos());
+ assertEquals(7, kr.getMatch(1).getEndPos());
+
+ SpanElementQuery seq = new SpanElementQuery("base", "np");
+ SpanClassQuery scq2 = new SpanClassQuery(seq, (byte) 2);
+
+ kr = ki.search(scq2, (short) 10);
+ assertEquals((long) 4, kr.getTotalResults());
+ assertEquals(0, kr.getMatch(0).getStartPos());
+ assertEquals(1, kr.getMatch(0).getEndPos());
+ assertEquals(2, kr.getMatch(1).getStartPos());
+ assertEquals(4, kr.getMatch(1).getEndPos());
+ assertEquals(2, kr.getMatch(2).getStartPos());
+ assertEquals(7, kr.getMatch(2).getEndPos());
+ assertEquals(5, kr.getMatch(3).getStartPos());
+ assertEquals(7, kr.getMatch(3).getEndPos());
+
+ // match nps as relation targets (right side)
+ // return all nps whose children are articles
+ SpanSegmentQuery ssq2 = new SpanSegmentQuery(sfq, scq2);
+ kr = ki.search(ssq2, (short) 10);
+ assertEquals((long) 2, kr.getTotalResults());
+ assertEquals(2, kr.getMatch(0).getStartPos());
+ assertEquals(4, kr.getMatch(0).getEndPos());
+ assertEquals(5, kr.getMatch(1).getStartPos());
+ assertEquals(7, kr.getMatch(1).getEndPos());
+
+ // NOTE: cannot match the span id of the embedded relation
+ // target and the np. So the segment match here is only by
+ // positions. All nps in the same position will be matches.
+
+ // return the articles whos parents are nps
+ SpanFocusQuery sfq2 = new SpanFocusQuery(ssq2, (byte) 1);
+ sfq2.setSorted(false);
+ assertEquals("focus(1: spanSegment(focus(2: spanSegment({1: source:"
+ + "{2: target:spanRelation(base:>:child-of)}}, "
+ + "{1: spanTermWithId(base:pos:ART)})), "
+ + "{2: <base:np />}))", sfq2.toString());
+
+ kr = ki.search(sfq2, (short) 10);
assertEquals((long) 2, kr.getTotalResults());
assertEquals(2, kr.getMatch(0).getStartPos());
@@ -604,20 +710,9 @@
assertEquals(5, kr.getMatch(1).getStartPos());
assertEquals(6, kr.getMatch(1).getEndPos());
- // return all nps whose children are articles
- SpanFocusQuery sf = new SpanFocusQuery(rm, (byte) 1);
- assertEquals(
- "focus(1: focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(base:>:child-of), {2: spanTermWithId(base:pos:ART)})), {1: <base:np />})))",
- sf.toString());
-
- kr = ki.search(sf, (short) 10);
-
- assertEquals((long) 2, kr.getTotalResults());
- assertEquals(2, kr.getMatch(0).getStartPos());
- assertEquals(4, kr.getMatch(0).getEndPos());
- assertEquals(5, kr.getMatch(1).getStartPos());
- assertEquals(7, kr.getMatch(1).getEndPos());
-
+ // for (Match m : kr.getMatches()) {
+ // System.out.println(m.getStartPos() + " " + m.getEndPos());
+ // }
}
/**
@@ -625,14 +720,14 @@
*
* */
@Test
- public void testCase10 () throws IOException {
+ public void testCase10a() throws IOException {
ki.addDoc(createFieldDoc2());
ki.commit();
SpanAttributeQuery aq = new SpanAttributeQuery(new SpanTermQuery(
new Term("base", "@:case=accusative")), true);
kr = ki.search(aq, (short) 10);
- assertEquals((long) 2, kr.getTotalResults());
+ assertEquals((long) 3, kr.getTotalResults());
SpanRelationQuery srq = new SpanRelationQuery(new SpanTermQuery(
new Term("base", ">:child-of")), true);
@@ -651,25 +746,39 @@
assertEquals(4, kr.getMatch(0).getEndPos());
assertEquals(5, kr.getMatch(1).getStartPos());
assertEquals(7, kr.getMatch(1).getEndPos());
-
- // Returning relations whose source has a specific attribute
- SpanFocusQuery fqr = new SpanFocusQuery(swaq,
- srq.getTempClassNumbers());
- fqr.setMatchTemporaryClass(true);
- fqr.setRemoveTemporaryClasses(true);
-
- kr = ki.search(fqr, (short) 10);
- assertEquals((long) 2, kr.getTotalResults());
- assertEquals(2, kr.getMatch(0).getStartPos());
- assertEquals(7, kr.getMatch(0).getEndPos());
- assertEquals(4, kr.getMatch(1).getStartPos());
- assertEquals(7, kr.getMatch(1).getEndPos());
+
+ // Returning relations whose source has a specific attribute
+ SpanFocusQuery fqr = new SpanFocusQuery(swaq,
+ srq.getTempClassNumbers());
+ fqr.setMatchTemporaryClass(true);
+ fqr.setRemoveTemporaryClasses(true);
+ assertEquals("focus(#[1,2]spanRelationWithAttribute(focus(1: "
+ + "{1: source:{2: target:spanRelation(base:>:child-of)}}), "
+ + "spanAttribute(base:@:case=accusative)))", fqr.toString());
+
+ kr = ki.search(fqr, (short) 10);
+ assertEquals((long) 2, kr.getTotalResults());
+ assertEquals(2, kr.getMatch(0).getStartPos());
+ assertEquals(7, kr.getMatch(0).getEndPos());
+ assertEquals(4, kr.getMatch(1).getStartPos());
+ assertEquals(7, kr.getMatch(1).getEndPos());
// Matching relation target nodes with an attribute
SpanFocusQuery sfq2 = new SpanFocusQuery(srq, (byte) 2);
+ sfq2.setSorted(false);
SpanWithAttributeQuery swaq2 = new SpanWithAttributeQuery(sfq2, aq,
true);
+ kr = ki.search(aq, (short) 20);
+
+ // for (Match m : kr.getMatches()) {
+ // System.out.println(m.getStartPos() + " " + m.getEndPos());
+ // }
+ kr = ki.search(swaq2, (short) 10);
+ assertEquals((long) 2, kr.getTotalResults());
+ assertEquals(5, kr.getMatch(1).getStartPos());
+ assertEquals(7, kr.getMatch(1).getEndPos());
+
// Returning relations whose target has a specific attribute
SpanFocusQuery fqr2 = new SpanFocusQuery(swaq2,
srq.getTempClassNumbers());
@@ -677,15 +786,127 @@
fqr2.setRemoveTemporaryClasses(true);
kr = ki.search(fqr2, (short) 10);
+ assertEquals((long) 2, kr.getTotalResults());
+ assertEquals(2, kr.getMatch(0).getStartPos());
+ assertEquals(7, kr.getMatch(0).getEndPos());
+ assertEquals(5, kr.getMatch(1).getStartPos());
+ assertEquals(7, kr.getMatch(1).getEndPos());
+ }
- // for (Match m : kr.getMatches()) {
- // System.out.println(m.getStartPos() + " " + m.getEndPos());
- // }
+ /**
+ * Relation whose nodes have a specific attribute. Alternative
+ * query (actually used in serialization)
+ * */
+ @Test
+ public void testCase10b() throws IOException {
+ ki.addDoc(createFieldDoc2());
+ ki.commit();
+ SpanAttributeQuery aq = new SpanAttributeQuery(new SpanTermQuery(
+ new Term("base", "@:case=accusative")), true);
+ kr = ki.search(aq, (short) 10);
+ assertEquals((long) 3, kr.getTotalResults());
+
+ SpanRelationQuery srq = new SpanRelationQuery(new SpanTermQuery(
+ new Term("base", ">:child-of")), true);
+ srq.setSourceClass((byte) 1);
+ srq.setTargetClass((byte) 2);
+ kr = ki.search(srq, (short) 20);
+ assertEquals((long) 13, kr.getTotalResults());
+
+ // Matching relation source node with an attribute
+ SpanWithAttributeQuery swaq = new SpanWithAttributeQuery(aq, true);
+ SpanSegmentQuery ssq = new SpanSegmentQuery(srq, swaq);
+
+ assertEquals(
+ "spanSegment({1: source:{2: target:spanRelation(base:>:child-of)}}, "
+ + "spanWithAttribute(spanAttribute(base:@:case=accusative)))",
+ ssq.toString());
+
+ kr = ki.search(ssq, (short) 10);
assertEquals((long) 2, kr.getTotalResults());
assertEquals(2, kr.getMatch(0).getStartPos());
assertEquals(4, kr.getMatch(0).getEndPos());
assertEquals(5, kr.getMatch(1).getStartPos());
assertEquals(7, kr.getMatch(1).getEndPos());
+
+ // Matching relation target nodes with an attribute
+ // NOTE: swaq must be the first parameter
+ SpanFocusQuery sfq2 = new SpanFocusQuery(srq, (byte) 2);
+ sfq2.setSorted(false);
+ SpanSegmentQuery ssq2 = new SpanSegmentQuery(swaq, sfq2);
+
+ kr = ki.search(ssq2, (short) 10);
+ assertEquals((long) 2, kr.getTotalResults());
+ assertEquals(2, kr.getMatch(0).getStartPos());
+ assertEquals(7, kr.getMatch(0).getEndPos());
+ assertEquals(5, kr.getMatch(1).getStartPos());
+ assertEquals(7, kr.getMatch(1).getEndPos());
+
+ // Matching specific relation source node with an attribute
+ SpanElementQuery seq = new SpanElementQuery("base", "np");
+ swaq = new SpanWithAttributeQuery(seq, aq, true);
+ ssq = new SpanSegmentQuery(srq, swaq);
+
+ assertEquals(
+ "spanSegment({1: source:{2: target:spanRelation(base:>:child-of)}}, "
+ + "spanElementWithAttribute(<base:np />, "
+ + "spanAttribute(base:@:case=accusative)))",
+ ssq.toString());
+
+ kr = ki.search(ssq, (short) 10);
+ assertEquals((long) 2, kr.getTotalResults());
+ assertEquals(2, kr.getMatch(0).getStartPos());
+ assertEquals(4, kr.getMatch(0).getEndPos());
+ assertEquals(5, kr.getMatch(1).getStartPos());
+ assertEquals(7, kr.getMatch(1).getEndPos());
+ }
+
+ /**
+ * Matching both relation nodes whose a specific attribute
+ * */
+ @Test
+ public void testCase11() throws IOException {
+ ki.addDoc(createFieldDoc2());
+ ki.commit();
+
+ SpanAttributeQuery aq = new SpanAttributeQuery(new SpanTermQuery(
+ new Term("base", "@:case=accusative")), true);
+ kr = ki.search(aq, (short) 10);
+ assertEquals((long) 3, kr.getTotalResults());
+
+ SpanAttributeQuery aq2 = new SpanAttributeQuery(new SpanTermQuery(
+ new Term("base", "@:case=accusative")), true);
+ kr = ki.search(aq2, (short) 10);
+ assertEquals((long) 3, kr.getTotalResults());
+
+ SpanRelationQuery srq = new SpanRelationQuery(new SpanTermQuery(
+ new Term("base", ">:child-of")), true);
+ srq.setSourceClass((byte) 1);
+ srq.setTargetClass((byte) 2);
+ kr = ki.search(srq, (short) 20);
+ assertEquals((long) 13, kr.getTotalResults());
+
+ SpanWithAttributeQuery swaq1 = new SpanWithAttributeQuery(aq, true);
+ SpanWithAttributeQuery swaq2 = new SpanWithAttributeQuery(aq2, true);
+
+ kr = ki.search(swaq1, (short) 10);
+ assertEquals((long) 3, kr.getTotalResults());
+
+ SpanRelationMatchQuery srmq = new SpanRelationMatchQuery(srq, swaq1,
+ swaq2, true);
+ assertEquals(
+ "focus(#[1,2]spanSegment(spanWithAttribute(spanAttribute(base:@:case=accusative)), "
+ + "focus(#2: spanSegment({1: source:{2: target:spanRelation(base:>:child-of)}}, "
+ + "spanWithAttribute(spanAttribute(base:@:case=accusative))))))",
+ srmq.toString());
+ kr = ki.search(srmq, (short) 10);
+ assertEquals((long) 1, kr.getTotalResults());
+ assertEquals(2, kr.getMatch(0).getStartPos());
+ assertEquals(7, kr.getMatch(0).getEndPos());
+
+ // for (Match m : kr.getMatches()) {
+ // System.out.println(m.getStartPos() + " " + m.getEndPos());
+ // }
}
}
diff --git a/src/test/java/de/ids_mannheim/korap/query/TestSpanReferenceQueryJSON.java b/src/test/java/de/ids_mannheim/korap/query/TestSpanReferenceQueryJSON.java
index a5a65b4..b9ef7c4 100644
--- a/src/test/java/de/ids_mannheim/korap/query/TestSpanReferenceQueryJSON.java
+++ b/src/test/java/de/ids_mannheim/korap/query/TestSpanReferenceQueryJSON.java
@@ -23,10 +23,12 @@
// 'cat="V" & cat="NP" & cat="PP" & #2 . #1 & #1 ->dep #3 &
// #3 . #2
+
assertEquals(
- "spanReference(spanNext({3: tokens:p:P}, focus(2: focus(#[1,2]spanSegment(focus(#2: "
- + "spanSegment(spanRelation(tokens:>:mate/d:HEAD), focus(1: spanNext("
- + "{2: tokens:p:V}, {1: <tokens:c:NP />})))), {3: tokens:p:P})))), 3)",
+ "spanReference(spanNext({3: tokens:p:P}, "
+ + "focus(2: focus(#[1,2]spanSegment({3: tokens:p:P}, "
+ + "focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
+ + "focus(1: spanNext({2: tokens:p:V}, {1: <tokens:c:NP />})))))))), 3)",
sq.toString());
}
@@ -42,9 +44,9 @@
// 'cat="V" & cat="NP" & cat="PP" & #2 . #1 & #1 ->dep #3 &
// #2 . #3
assertEquals(
- "spanReference(spanNext(focus(2: focus(#[1,2]spanSegment(focus(#2: "
- + "spanSegment(spanRelation(tokens:>:mate/d:HEAD), focus(1: spanNext("
- + "{2: tokens:p:V}, {1: <tokens:c:NP />})))), {3: tokens:p:P}))), "
+ "spanReference(spanNext(focus(2: focus(#[1,2]spanSegment({3: tokens:p:P}, "
+ + "focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
+ + "focus(1: spanNext({2: tokens:p:V}, {1: <tokens:c:NP />}))))))), "
+ "{3: tokens:p:P}), 3)", sq.toString());
}
@@ -59,10 +61,11 @@
// 'cat="VP" & cat="NP" & cat="PP" & #1 . #2 & #2 . #3 & #1 .
// #3 & #2 ->dep #1'
assertEquals(
- "spanReference(focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
+ "spanReference(focus(#[1,2]spanSegment({1: <tokens:c:VP />}, "
+ + "focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
+ "focus(2: spanReference(spanNext(focus(1: spanNext(focus(2: spanNext({1: <tokens:c:VP />}, "
- + "{2: <tokens:c:NP />})), {3: <tokens:c:PP />})), {3: <tokens:c:PP />}), 3)))), "
- + "{1: <tokens:c:VP />})), 1)", sq.toString());
+ + "{2: <tokens:c:NP />})), {3: <tokens:c:PP />})), {3: <tokens:c:PP />}), 3)))))), 1)",
+ sq.toString());
}
@@ -70,6 +73,7 @@
public void testDistanceReferences () throws QueryException {
// ND: I don't understand what this query should be about ...
+ // EM: There was just a bug with multiple distance
String filepath = getClass().getResource(
"/queries/reference/bug-multiple-distance-simple.jsonld")
.getFile();
@@ -88,14 +92,12 @@
// 'cat="VP" & cat="NP" & cat="PP" & #1 . #2 & #2 . #3 & #1 .
// #3 & #2 ->dep #1'
- assertEquals("spanReference(" + "focus(" + "#[1,2]spanSegment("
- + "focus(" + "#2: spanSegment("
- + "spanRelation(tokens:>:stanford/d:tag), " + "focus("
- + "2: spanDistance(" + "focus(" + "1: spanDistance("
- + "<tokens:c:vb />, " + "{1: <tokens:c:prp />}, "
- + "[(w[1:1], notOrdered, notExcluded)]" + ")" + "), "
- + "{2: <tokens:c:nn />}, " + "[(w[1:3], ordered, notExcluded)]"
- + ")" + ")" + ")" + "), " + "{1: <tokens:c:prp />}" + ")"
- + "), 1" + ")", sq.toString());
+ assertEquals(
+ "spanReference(focus(#[1,2]spanSegment({1: <tokens:c:prp />}, "
+ + "focus(#2: spanSegment(spanRelation(tokens:>:stanford/d:tag), "
+ + "focus(2: spanDistance(focus(1: spanDistance(<tokens:c:vb />, "
+ + "{1: <tokens:c:prp />}, [(w[1:1], notOrdered, notExcluded)])), "
+ + "{2: <tokens:c:nn />}, [(w[1:3], ordered, notExcluded)])))))), 1)",
+ sq.toString());
}
}
diff --git a/src/test/java/de/ids_mannheim/korap/query/TestSpanRelationQueryJSON.java b/src/test/java/de/ids_mannheim/korap/query/TestSpanRelationQueryJSON.java
index 3ba5a66..7e1a4ab 100644
--- a/src/test/java/de/ids_mannheim/korap/query/TestSpanRelationQueryJSON.java
+++ b/src/test/java/de/ids_mannheim/korap/query/TestSpanRelationQueryJSON.java
@@ -17,10 +17,31 @@
"/queries/relation/any-source-with-attribute.json").getFile();
SpanQueryWrapper sqwi = getJSONQuery(filepath);
SpanQuery sq = sqwi.toQuery();
+
assertEquals(
- "focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
- + "spanElementWithAttribute(<tokens:c: />, spanAttribute(tokens:type:case:accusative)))), "
- + "<tokens:c:vp />))", sq.toString());
+ "focus(#[1,2]spanSegment(<tokens:c:vp />, "
+ + "focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
+ + "spanWithAttribute(spanAttribute(tokens:type:case:accusative))))))",
+ sq.toString());
+ }
+
+ @Test
+ public void testMatchAnyRelationTargetWithAttribute() throws QueryException {
+ String filepath = getClass().getResource(
+ "/queries/relation/any-target-with-attribute.json").getFile();
+ SpanQueryWrapper sqwi = getJSONQuery(filepath);
+ SpanQuery sq = sqwi.toQuery();
+ assertEquals(
+ // "focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
+ // +
+ // "<tokens:c:vp />)), spanWithAttribute(spanAttribute(tokens:type:case:accusative))))",
+ //
+ "focus(#[1,2]spanSegment(spanWithAttribute(spanAttribute(tokens:type:case:accusative)), " +
+ "focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
+ + "<tokens:c:vp />))))",
+ sq.toString());
+
+ // System.out.println(sq.toString());
}
@Test
@@ -31,25 +52,28 @@
.getFile();
SpanQueryWrapper sqwi = getJSONQuery(filepath);
SpanQuery sq = sqwi.toQuery();
- assertEquals(
- "focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
- + "spanElementWithAttribute(<tokens:c:np />, spanAttribute(tokens:type:case:accusative)))), "
- + "<tokens:c:vp />))", sq.toString());
+
+ assertEquals("focus(#[1,2]spanSegment(<tokens:c:vp />, "
+ + "focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
+ + "spanElementWithAttribute(<tokens:c:np />, "
+ + "spanAttribute(tokens:type:case:accusative))))))",
+ sq.toString());
}
@Test
- public void testMatchAnyRelationNodeWithAttribute() throws QueryException {
+ public void testMatchBothRelationNodeWithAttribute() throws QueryException {
String filepath = getClass().getResource(
- "/queries/relation/any-node-with-attribute.json").getFile();
+ "/queries/relation/both-operands-with-attribute.json")
+ .getFile();
SpanQueryWrapper sqwi = getJSONQuery(filepath);
SpanQuery sq = sqwi.toQuery();
assertEquals(
- "focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
- + "spanElementWithAttribute(<tokens:c: />, spanAttribute(tokens:type:case:accusative)))), "
- + "spanElementWithAttribute(<tokens:c: />, spanAttribute(tokens:type:case:accusative))))",
+ "focus(#[1,2]spanSegment(spanElementWithAttribute(<tokens:c: />, "
+ + "spanAttribute(tokens:type:case:accusative)), "
+ + "focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
+ + "spanElementWithAttribute(<tokens:c: />, "
+ + "spanAttribute(tokens:type:case:accusative))))))",
sq.toString());
-
- System.out.println(sq.toString());
}
@Test
@@ -86,7 +110,8 @@
SpanQueryWrapper sqwi = getJSONQuery(filepath);
SpanQuery sq = sqwi.toQuery();
assertEquals(
- "focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), <tokens:c:s />)), <tokens:c:vp />))",
+ "focus(#[1,2]spanSegment(<tokens:c:vp />, "
+ + "focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), <tokens:c:s />))))",
sq.toString());
}
@@ -99,8 +124,8 @@
SpanQueryWrapper sqwi = getJSONQuery(filepath);
SpanQuery sq = sqwi.toQuery();
assertEquals(
- "focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
- + "spanElementWithAttribute(<tokens:c:s />, spanAttribute(tokens:@root)))), <tokens:c:vp />))",
+ "focus(#[1,2]spanSegment(<tokens:c:vp />, focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
+ + "spanElementWithAttribute(<tokens:c:s />, spanAttribute(tokens:@root))))))",
sq.toString());
}
@@ -113,8 +138,8 @@
SpanQueryWrapper sqwi = getJSONQuery(filepath);
SpanQuery sq = sqwi.toQuery();
assertEquals(
- "focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
- + "spanElementWithAttribute(<tokens:c:s />, spanAttribute(tokens:type:top)))), <tokens:c:vp />))",
+ "focus(#[1,2]spanSegment(<tokens:c:vp />, focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
+ + "spanElementWithAttribute(<tokens:c:s />, spanAttribute(tokens:type:top))))))",
sq.toString());
}
@@ -151,8 +176,8 @@
SpanQueryWrapper sqwi = getJSONQuery(filepath);
SpanQuery sq = sqwi.toQuery();
assertEquals(
- "focus(2: focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation("
- + "tokens:>:mate/d:HEAD), {1: <tokens:c:s />})), {2: <tokens:c:np />})))",
+ "focus(2: focus(#[1,2]spanSegment({2: <tokens:c:np />}, "
+ + "focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), {1: <tokens:c:s />})))))",
sq.toString());
}
diff --git a/src/test/resources/queries/relation/any-source-with-attribute.json b/src/test/resources/queries/relation/any-source-with-attribute.json
index 6154f18..8a4582d 100644
--- a/src/test/resources/queries/relation/any-source-with-attribute.json
+++ b/src/test/resources/queries/relation/any-source-with-attribute.json
@@ -5,7 +5,6 @@
"operands": [
{
"@type": "koral:span",
- "layer": "c",
"match": "match:eq",
"attr": {
"@type": "koral:term",
diff --git a/src/test/resources/queries/relation/any-target-with-attribute.json b/src/test/resources/queries/relation/any-target-with-attribute.json
new file mode 100644
index 0000000..63fdd14
--- /dev/null
+++ b/src/test/resources/queries/relation/any-target-with-attribute.json
@@ -0,0 +1,33 @@
+{
+ "query": {
+ "@type": "koral:group",
+ "operation": "operation:relation",
+ "operands": [
+ {
+ "@type": "koral:span",
+ "layer": "c",
+ "key": "vp"
+ },
+ {
+ "@type": "koral:span",
+ "match": "match:eq",
+ "attr": {
+ "@type": "koral:term",
+ "layer": "type",
+ "key": "case:accusative",
+ "match": "match:eq"
+ }
+ }
+ ],
+ "relType": {
+ "@type": "koral:relation",
+ "wrap": {
+ "@type": "koral:term",
+ "foundry": "mate",
+ "layer": "d",
+ "key": "HEAD"
+ }
+ }
+ },
+ "meta": {}
+}
\ No newline at end of file
diff --git a/src/test/resources/queries/relation/any-node-with-attribute.json b/src/test/resources/queries/relation/both-operands-with-attribute.json
similarity index 100%
rename from src/test/resources/queries/relation/any-node-with-attribute.json
rename to src/test/resources/queries/relation/both-operands-with-attribute.json