Repository: incubator-rya Updated Branches: refs/heads/master 7743a42a5 -> 193723396
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/01489efb/extras/rya.reasoning/src/test/java/mvm/rya/reasoning/ReasonerFactTest.java ---------------------------------------------------------------------- diff --git a/extras/rya.reasoning/src/test/java/mvm/rya/reasoning/ReasonerFactTest.java b/extras/rya.reasoning/src/test/java/mvm/rya/reasoning/ReasonerFactTest.java new file mode 100644 index 0000000..1859cd0 --- /dev/null +++ b/extras/rya.reasoning/src/test/java/mvm/rya/reasoning/ReasonerFactTest.java @@ -0,0 +1,277 @@ +package mvm.rya.reasoning; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.util.ArrayList; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import org.openrdf.model.Statement; +import org.openrdf.model.URI; +import org.openrdf.model.impl.StatementImpl; +import org.openrdf.model.vocabulary.OWL; +import org.openrdf.model.vocabulary.RDFS; + +public class ReasonerFactTest { + static final String wordnet = "http://www.w3.org/2006/03/wn/wn20/instances/"; + static final String wnSchema = "http://www.w3.org/2006/03/wn/wn20/schema/"; + static final URI[] nodes = { + TestUtils.uri(wordnet, "synset-entity-noun-1"), + TestUtils.uri(wordnet, "synset-physical_entity-noun-1"), + TestUtils.uri(wordnet, "synset-object-noun-1"), + TestUtils.uri(wordnet, "synset-whole-noun-2"), + TestUtils.uri(wordnet, "synset-living_thing-noun-1"), + TestUtils.uri(wordnet, "synset-organism-noun-1"), + TestUtils.uri(wordnet, "synset-person-noun-1"), + TestUtils.uri(wordnet, "synset-engineer-noun-1"), + TestUtils.uri(wordnet, "synset-programmer-noun-1") + }; + static final URI hyper = TestUtils.uri(wnSchema, "hypernymOf"); + static final Schema schema = new Schema(); + static final ArrayList<ArrayList<Fact>> hierarchy = new ArrayList<>(); + static final int MAX_LEVEL = 3; + + static Fact connect(int i, int j) { + return new Fact(nodes[i], hyper, nodes[j]); + } + + static Fact connectTransitive(int i, int j, int source, int t) { + return new Fact(nodes[i], hyper, nodes[j], t, OwlRule.PRP_TRP, + nodes[source]); + } + + @Before + public void buildHierarchy() { + hierarchy.add(new ArrayList<Fact>()); + int max = 8; + for (int i = 0; i < max; i++) { + hierarchy.get(0).add(connect(i, i+1)); + } + for (int level = 1; level <= MAX_LEVEL; level++) { + max = max / 2; + hierarchy.add(new ArrayList<Fact>()); + int d = (int) Math.pow(2, level); + for (int i = 0; i < max; i++) { + Fact fact = connectTransitive(i*d, (i*d)+d, (i*d)+(d/2), level); + ArrayList<Fact> previousLevel = hierarchy.get(level-1); + Fact sourceA = previousLevel.get(i*2); + Fact sourceB = previousLevel.get((i*2)+1); + fact.addSource(sourceA); + fact.addSource(sourceB); + hierarchy.get(level).add(fact); + } + } + } + + @Test + public void testBaseSpan() { + Assert.assertEquals("Input triple should have span=1", + 1, hierarchy.get(0).get(0).span()); + } + + @Test + public void testSpan() { + Assert.assertEquals("Iteration 1 triple should have span=2", + 2, hierarchy.get(1).get(0).span()); + } + + @Test + public void testMultilevelSpan() { + Assert.assertEquals("Iteration 3 triple should have span=8", + 8, hierarchy.get(3).get(0).span()); + } + + @Test + public void testSourceNodes() { + Assert.assertTrue("Transitive link 0 to 4 should have source nodes 1-3", + hierarchy.get(2).get(0).derivation.sourceNodes.contains(nodes[1]) && + hierarchy.get(2).get(0).derivation.sourceNodes.contains(nodes[2]) && + hierarchy.get(2).get(0).derivation.sourceNodes.contains(nodes[3]) && + hierarchy.get(2).get(0).derivation.sourceNodes.size() == 3); + } + + @Test + public void testTripleEquality() { + Fact a = hierarchy.get(2).get(0); + String s = a.getSubject().stringValue(); + String p = a.getPredicate().stringValue(); + String o = a.getObject().stringValue(); + Fact b = new Fact(TestUtils.uri("", s), + TestUtils.uri("", p), TestUtils.uri("", o)); + Assert.assertEquals("Triple equality should be based on (s, p, o) alone", a, b); + } + + @Test + public void testTripleHashCode() { + Fact a = hierarchy.get(2).get(0); + String s = a.getSubject().stringValue(); + String p = a.getPredicate().stringValue(); + String o = a.getObject().stringValue(); + Fact b = new Fact(TestUtils.uri("", s), + TestUtils.uri("", p), TestUtils.uri("", o)); + Assert.assertEquals("hashCode should be based on (s, p, o) alone", + a.hashCode(), b.hashCode()); + } + + @Test + public void testTripleInequality() { + Fact a = hierarchy.get(2).get(0); + Fact b = a.clone(); + Statement stmt = new StatementImpl(TestUtils.uri(a.getSubject().stringValue()), + a.getPredicate(), a.getObject()); // subject will have extra prefix + b.setTriple(stmt); + Assert.assertFalse("Triple equality should be based on (s, p, o)", a.equals(b)); + } + + @Test + public void testClone() { + Fact a = hierarchy.get(2).get(0); + Fact b = a.clone(); + Assert.assertEquals("clone should equal() original", a, b); + Assert.assertEquals("clone.subject should be equal to original", + a.getSubject(), b.getSubject()); + Assert.assertEquals("clone.predicate should be equal to original", + a.getPredicate(), b.getPredicate()); + Assert.assertEquals("clone.object should be equal to original", + a.getObject(), b.getObject()); + Assert.assertEquals("clone.derivation should be equal to original", + a.getDerivation(), b.getDerivation()); + Assert.assertEquals("clone.useful should be equal to original", + a.isUseful(), b.isUseful()); + Assert.assertEquals("clone.span() should equal original", + a.span(), b.span()); + } + + @Test + public void testSerializeDeserialize() throws Exception { + Fact a = hierarchy.get(2).get(0); + Fact b = new Fact(); + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + a.write(new DataOutputStream(bytes)); + b.readFields(new DataInputStream(new ByteArrayInputStream(bytes.toByteArray()))); + Assert.assertEquals("deserialized triple should equal() original", a, b); + Assert.assertEquals("deserialized subject should be equal to original", + a.getSubject(), b.getSubject()); + Assert.assertEquals("deserialized predicate should be equal to original", + a.getPredicate(), b.getPredicate()); + Assert.assertEquals("deserialized object should be equal to original", + a.getObject(), b.getObject()); + Assert.assertEquals("deserialized derivation should be equal to original", + a.getDerivation(), b.getDerivation()); + Assert.assertEquals("deserialized useful should be equal to original", + a.isUseful(), b.isUseful()); + Assert.assertEquals("deserialized span() should equal original", a.span(), b.span()); + } + + @Test + public void testSerializeDeserializeString() throws Exception { + Fact a = TestUtils.fact(hyper, TestUtils.uri(wnSchema, "gloss"), + TestUtils.stringLiteral("(a word that is more generic than a given word)")); + Fact b = new Fact(); + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + a.write(new DataOutputStream(bytes)); + b.readFields(new DataInputStream(new ByteArrayInputStream(bytes.toByteArray()))); + Assert.assertEquals("deserialized triple should equal() original", a, b); + Assert.assertEquals("deserialized subject should be equal to original", + a.getSubject(), b.getSubject()); + Assert.assertEquals("deserialized predicate should be equal to original", + a.getPredicate(), b.getPredicate()); + Assert.assertEquals("deserialized object should be equal to original", + a.getObject(), b.getObject()); + Assert.assertEquals("deserialized derivation should be equal to original", + a.getDerivation(), b.getDerivation()); + Assert.assertEquals("deserialized useful should be equal to original", + a.isUseful(), b.isUseful()); + Assert.assertEquals("deserialized span() should equal original", a.span(), b.span()); + } + + @Test + public void testSerializeDeserializeLanguage() throws Exception { + Fact a = TestUtils.fact(hyper, TestUtils.uri(wnSchema, "gloss"), + TestUtils.stringLiteral("(a word that is more generic than a given word)", "e")); + Fact b = new Fact(); + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + a.write(new DataOutputStream(bytes)); + b.readFields(new DataInputStream(new ByteArrayInputStream(bytes.toByteArray()))); + Assert.assertEquals("deserialized triple should equal() original", a, b); + Assert.assertEquals("deserialized subject should be equal to original", + a.getSubject(), b.getSubject()); + Assert.assertEquals("deserialized predicate should be equal to original", + a.getPredicate(), b.getPredicate()); + Assert.assertEquals("deserialized object should be equal to original", + a.getObject(), b.getObject()); + Assert.assertEquals("deserialized derivation should be equal to original", + a.getDerivation(), b.getDerivation()); + Assert.assertEquals("deserialized useful should be equal to original", + a.isUseful(), b.isUseful()); + Assert.assertEquals("deserialized span() should equal original", a.span(), b.span()); + } + + @Test + public void testSerializeDeserializeInt() throws Exception { + Fact a = TestUtils.fact(TestUtils.uri(wnSchema, "inSynset"), + OWL.MAXCARDINALITY, + TestUtils.intLiteral("1")); + Fact b = new Fact(); + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + a.write(new DataOutputStream(bytes)); + b.readFields(new DataInputStream(new ByteArrayInputStream(bytes.toByteArray()))); + Assert.assertEquals("deserialized triple should equal() original", a, b); + Assert.assertEquals("deserialized subject should be equal to original", + a.getSubject(), b.getSubject()); + Assert.assertEquals("deserialized predicate should be equal to original", + a.getPredicate(), b.getPredicate()); + Assert.assertEquals("deserialized object should be equal to original", + a.getObject(), b.getObject()); + Assert.assertEquals("deserialized derivation should be equal to original", + a.getDerivation(), b.getDerivation()); + Assert.assertEquals("deserialized useful should be equal to original", + a.isUseful(), b.isUseful()); + Assert.assertEquals("deserialized span() should equal original", a.span(), b.span()); + } + + @Test + public void testSerializeDeserializeBnode() throws Exception { + Fact a = TestUtils.fact(TestUtils.bnode("foo"), + RDFS.SUBCLASSOF, TestUtils.bnode("bar")); + Fact b = new Fact(); + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + a.write(new DataOutputStream(bytes)); + b.readFields(new DataInputStream(new ByteArrayInputStream(bytes.toByteArray()))); + Assert.assertEquals("deserialized triple should equal() original", a, b); + Assert.assertEquals("deserialized subject should be equal to original", + a.getSubject(), b.getSubject()); + Assert.assertEquals("deserialized predicate should be equal to original", + a.getPredicate(), b.getPredicate()); + Assert.assertEquals("deserialized object should be equal to original", + a.getObject(), b.getObject()); + Assert.assertEquals("deserialized derivation should be equal to original", + a.getDerivation(), b.getDerivation()); + Assert.assertEquals("deserialized useful should be equal to original", + a.isUseful(), b.isUseful()); + Assert.assertEquals("deserialized span() should equal original", a.span(), b.span()); + } +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/01489efb/extras/rya.reasoning/src/test/java/mvm/rya/reasoning/SchemaReasoningTest.java ---------------------------------------------------------------------- diff --git a/extras/rya.reasoning/src/test/java/mvm/rya/reasoning/SchemaReasoningTest.java b/extras/rya.reasoning/src/test/java/mvm/rya/reasoning/SchemaReasoningTest.java new file mode 100644 index 0000000..0f1d3c8 --- /dev/null +++ b/extras/rya.reasoning/src/test/java/mvm/rya/reasoning/SchemaReasoningTest.java @@ -0,0 +1,330 @@ +package mvm.rya.reasoning; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import org.openrdf.model.Resource; +import org.openrdf.model.vocabulary.FOAF; +import org.openrdf.model.vocabulary.OWL; +import org.openrdf.model.vocabulary.RDFS; + +/** + * Test the application of the OWL RL/RDF schema ("scm-") rules. + */ +public class SchemaReasoningTest { + private Schema schema; + + /** + * Setup: load in test data + */ + @Before + public void insertData() { + schema = new Schema(); + // Lifted from the LUBM ontology: + schema.processTriple(TestUtils.statement(TestUtils.uri("Dean"), + RDFS.SUBCLASSOF, TestUtils.uri("Professor"))); + schema.processTriple(TestUtils.statement(TestUtils.uri("Professor"), + RDFS.SUBCLASSOF, TestUtils.uri("Faculty"))); + schema.processTriple(TestUtils.statement(TestUtils.uri("Faculty"), + RDFS.SUBCLASSOF, TestUtils.uri("Employee"))); + schema.processTriple(TestUtils.statement(TestUtils.uri("University"), + RDFS.SUBCLASSOF, TestUtils.uri("Organization"))); + schema.processTriple(TestUtils.statement(TestUtils.uri("ResearchGroup"), + RDFS.SUBCLASSOF, TestUtils.uri("Organization"))); + schema.processTriple(TestUtils.statement(TestUtils.uri("headOf"), + RDFS.SUBPROPERTYOF, TestUtils.uri("worksFor"))); + schema.processTriple(TestUtils.statement(TestUtils.uri("worksFor"), + RDFS.SUBPROPERTYOF, TestUtils.uri("memberOf"))); + schema.processTriple(TestUtils.statement(TestUtils.uri("advisor"), + RDFS.RANGE, TestUtils.uri("Professor"))); + schema.processTriple(TestUtils.statement(TestUtils.uri("hasAlumnus"), + RDFS.DOMAIN, TestUtils.uri("University"))); + // Not explicitly part of LUBM but helpful for a couple tests: + schema.processTriple(TestUtils.statement(TestUtils.uri("memberOf"), + RDFS.DOMAIN, TestUtils.uri("Person"))); + schema.processTriple(TestUtils.statement(TestUtils.uri("memberOf"), + RDFS.RANGE, TestUtils.uri("Organization"))); + schema.processTriple(TestUtils.statement(TestUtils.uri("researchSpecialty"), + RDFS.SUBPROPERTYOF, TestUtils.uri("researchInterest"))); + schema.closure(); + } + + /** + * scm-cls + */ + @Test + public void testSelfSubclass() throws Exception { + Assert.assertTrue("Any class should be its own superclass", + schema.getClass(TestUtils.uri("foo")).getSuperClasses().contains( + TestUtils.uri("foo"))); + } + @Test + public void testSelfEquivalentClass() throws Exception { + Assert.assertTrue("Any class should be its own equivalent", + schema.getClass(TestUtils.uri("foo")).getEquivalentClasses().contains( + TestUtils.uri("foo"))); + } + @Test + public void testSubclassOwlThing() throws Exception { + Assert.assertTrue("Any class should be a subclass of owl:Thing", + schema.getClass(TestUtils.uri("foo")).getSuperClasses().contains( + OWL.THING)); + } + + /** + * scm-sco + */ + @Test + public void testSubclassTransitivity() throws Exception { + Assert.assertTrue("Failed to infer indirect superclass", + schema.getClass(TestUtils.uri("Dean")).getSuperClasses().contains( + TestUtils.uri("Employee"))); + } + + /** + * scm-eqc1 + */ + @Test + public void testEquivalentImpliesSubclass() throws Exception { + schema.processTriple(TestUtils.statement(TestUtils.uri("Person"), + OWL.EQUIVALENTCLASS, FOAF.PERSON)); + Assert.assertTrue("Failed to infer subClassOf from equivalentClass", + schema.getClass(TestUtils.uri("Person")).getSuperClasses().contains( + FOAF.PERSON)); + } + + /** + * scm-eqc2 + */ + @Test + public void testSubclassImpliesEquivalence() throws Exception { + schema.processTriple(TestUtils.statement(FOAF.PERSON, + RDFS.SUBCLASSOF, + TestUtils.uri("Person"))); + schema.processTriple(TestUtils.statement(TestUtils.uri("Person"), + RDFS.SUBCLASSOF, + FOAF.PERSON)); + Assert.assertTrue("Failed to infer equivalentClass from subClassOf", + schema.getClass(FOAF.PERSON).getEquivalentClasses().contains( + TestUtils.uri("Person"))); + } + + /** + * scm-op, scm-dp + */ + @Test + public void testSelfSubproperty() throws Exception { + Assert.assertTrue("Any property should be its own superproperty", + schema.getProperty(TestUtils.uri("foo")).getSuperProperties().contains( + TestUtils.uri("foo"))); + } + @Test + public void testSelfEquivalentProperty() throws Exception { + Assert.assertTrue("Any property should be its own equivalent", + schema.getProperty(TestUtils.uri("foo")).getEquivalentProperties().contains( + TestUtils.uri("foo"))); + } + + /** + * scm-spo + */ + @Test + public void testSubpropertyTransitivity() throws Exception { + Assert.assertTrue("Failed to infer indirect superproperty", + schema.getProperty(TestUtils.uri("headOf")).getSuperProperties().contains( + TestUtils.uri("memberOf"))); + } + + /** + * scm-eqp1 + */ + @Test + public void testEquivalentImpliesSubproperty() throws Exception { + schema.processTriple(TestUtils.statement(TestUtils.uri("memberOf"), + OWL.EQUIVALENTPROPERTY, TestUtils.uri("test:memberOf"))); + Assert.assertTrue("Failed to infer subPropertyOf from equivalentProperty", + schema.getProperty(TestUtils.uri("test:memberOf")).getSuperProperties().contains( + TestUtils.uri("memberOf"))); + } + + /** + * scm-eqp2 + */ + @Test + public void testSubpropertyImpliesEquivalence() throws Exception { + schema.processTriple(TestUtils.statement(TestUtils.uri("advisor"), + RDFS.SUBPROPERTYOF, TestUtils.uri("test:advisor"))); + schema.processTriple(TestUtils.statement(TestUtils.uri("test:advisor"), + RDFS.SUBPROPERTYOF, TestUtils.uri("advisor"))); + Assert.assertTrue("Failed to infer equivalentProperty from mutual " + + "subPropertyOf statements", schema.getProperty( + TestUtils.uri("advisor")).getEquivalentProperties().contains( + TestUtils.uri("test:advisor"))); + } + + /** + * scm-dom1 + */ + @Test + public void testDomainSuperclass() throws Exception { + Assert.assertTrue("Failed to infer domain: superclass from domain: " + + "subclass", schema.getProperty(TestUtils.uri("hasAlumnus")).getDomain().contains( + TestUtils.uri("Organization"))); + } + + /** + * scm-dom2 + */ + @Test + public void testDomainInheritance() throws Exception { + Assert.assertTrue("Subproperty should inherit superproperty's domain", + schema.getProperty(TestUtils.uri("headOf")).getDomain().contains( + TestUtils.uri("Person"))); + } + + /** + * scm-rng1 + */ + @Test + public void testRangeSuperclass() throws Exception { + Assert.assertTrue("Failed to infer range: superclass from range: " + + "subclass", schema.getProperty(TestUtils.uri("advisor")).getRange().contains( + TestUtils.uri("Faculty"))); + } + + /** + * scm-rng2 + */ + @Test + public void testRangeInheritance() throws Exception { + Assert.assertTrue("Subproperty should inherit superproperty's range", + schema.getProperty(TestUtils.uri("headOf")).getRange().contains( + TestUtils.uri("Organization"))); + } + + + /** + * scm-hv + */ + @Test + public void testHasValueSubProp() throws Exception { + Resource c1 = TestUtils.bnode("c1"); + Resource c2 = TestUtils.bnode("c2"); + schema.processTriple(TestUtils.statement(c1, OWL.HASVALUE, + TestUtils.stringLiteral("big data"))); + schema.processTriple(TestUtils.statement(c1, OWL.ONPROPERTY, + TestUtils.uri("researchSpecialty"))); + schema.processTriple(TestUtils.statement(c2, OWL.HASVALUE, + TestUtils.stringLiteral("big data"))); + schema.processTriple(TestUtils.statement(c2, OWL.ONPROPERTY, + TestUtils.uri("researchInterest"))); + schema.closure(); + Assert.assertTrue("[hasValue x on <subproperty>] should be subclass of" + + " [hasValue x on <superproperty>]", + schema.getClass(c1).getSuperClasses().contains(c2)); + } + + /** + * scm-svf1 + */ + @Test + public void testSomeValuesSubClass() throws Exception { + Resource c1 = TestUtils.bnode("c1"); + Resource c2 = TestUtils.bnode("c2"); + schema.processTriple(TestUtils.statement(c1, OWL.SOMEVALUESFROM, + TestUtils.uri("ResearchGroup"))); + schema.processTriple(TestUtils.statement(c1, OWL.ONPROPERTY, + TestUtils.uri("worksFor"))); + schema.processTriple(TestUtils.statement(c2, OWL.SOMEVALUESFROM, + TestUtils.uri("Organization"))); + schema.processTriple(TestUtils.statement(c2, OWL.ONPROPERTY, + TestUtils.uri("worksFor"))); + schema.closure(); + Assert.assertTrue("[someValuesFrom <subclass> on p] should be subclass of" + + " [someValuesFrom <superclass> on p]", + schema.getClass(c1).getSuperClasses().contains(c2)); + } + + /** + * scm-svf2 + */ + @Test + public void testSomeValuesSubProp() throws Exception { + Resource c1 = TestUtils.bnode("c1"); + Resource c2 = TestUtils.bnode("c2"); + schema.processTriple(TestUtils.statement(c1, OWL.SOMEVALUESFROM, + TestUtils.uri("Organization"))); + schema.processTriple(TestUtils.statement(c1, OWL.ONPROPERTY, + TestUtils.uri("worksFor"))); + schema.processTriple(TestUtils.statement(c2, OWL.SOMEVALUESFROM, + TestUtils.uri("Organization"))); + schema.processTriple(TestUtils.statement(c2, OWL.ONPROPERTY, + TestUtils.uri("memberOf"))); + schema.closure(); + Assert.assertTrue("[someValuesFrom y on <subproperty>] should be subclass of" + + " [someValuesFrom y on <superproperty>]", + schema.getClass(c1).getSuperClasses().contains(c2)); + } + + /** + * scm-avf1 + */ + @Test + public void testAllValuesSubClass() throws Exception { + Resource c1 = TestUtils.bnode("c1"); + Resource c2 = TestUtils.bnode("c2"); + schema.processTriple(TestUtils.statement(c1, OWL.ALLVALUESFROM, + TestUtils.uri("ResearchGroup"))); + schema.processTriple(TestUtils.statement(c1, OWL.ONPROPERTY, + TestUtils.uri("worksFor"))); + schema.processTriple(TestUtils.statement(c2, OWL.ALLVALUESFROM, + TestUtils.uri("Organization"))); + schema.processTriple(TestUtils.statement(c2, OWL.ONPROPERTY, + TestUtils.uri("worksFor"))); + schema.closure(); + Assert.assertTrue("[allValuesFrom <subclass> on p] should be subclass of" + + " [allValuesFrom <superclass> on p]", + schema.getClass(c1).getSuperClasses().contains(c2)); + } + + /** + * scm-avf2 + */ + @Test + public void testAllValuesSubProp() throws Exception { + Resource c1 = TestUtils.bnode("c1"); + Resource c2 = TestUtils.bnode("c2"); + schema.processTriple(TestUtils.statement(c1, OWL.ALLVALUESFROM, + TestUtils.uri("University"))); + schema.processTriple(TestUtils.statement(c1, OWL.ONPROPERTY, + TestUtils.uri("worksFor"))); + schema.processTriple(TestUtils.statement(c2, OWL.ALLVALUESFROM, + TestUtils.uri("University"))); + schema.processTriple(TestUtils.statement(c2, OWL.ONPROPERTY, + TestUtils.uri("memberOf"))); + schema.closure(); + Assert.assertTrue("[allValuesFrom y on <superproperty>] should be subclass of" + + " [allValuesFrom y on <subproperty>]", + schema.getClass(c2).getSuperClasses().contains(c1)); + } +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/01489efb/extras/rya.reasoning/src/test/java/mvm/rya/reasoning/SchemaTest.java ---------------------------------------------------------------------- diff --git a/extras/rya.reasoning/src/test/java/mvm/rya/reasoning/SchemaTest.java b/extras/rya.reasoning/src/test/java/mvm/rya/reasoning/SchemaTest.java new file mode 100644 index 0000000..08bc36c --- /dev/null +++ b/extras/rya.reasoning/src/test/java/mvm/rya/reasoning/SchemaTest.java @@ -0,0 +1,284 @@ +package mvm.rya.reasoning; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.junit.Assert; +import org.junit.Test; +import org.openrdf.model.URI; +import org.openrdf.model.vocabulary.OWL; +import org.openrdf.model.vocabulary.RDF; +import org.openrdf.model.vocabulary.RDFS; +import org.openrdf.model.vocabulary.SKOS; + +public class SchemaTest { + URI lubm(String s) { + return TestUtils.uri("http://swat.cse.lehigh.edu/onto/univ-bench.owl", s); + } + + // Recognize useful schema data + @Test + public void testAcceptSubclass() throws Exception { + Assert.assertTrue(Schema.isSchemaTriple(TestUtils.statement( + lubm("Lecturer"), RDFS.SUBCLASSOF, lubm("Faculty")))); + } + @Test + public void testAcceptSubproperty() throws Exception { + Assert.assertTrue(Schema.isSchemaTriple(TestUtils.statement( + lubm("mastersDegreeFrom"), RDFS.SUBPROPERTYOF, lubm("degreeFrom")))); + } + @Test + public void testAcceptDomain() throws Exception { + Assert.assertTrue(Schema.isSchemaTriple(TestUtils.statement( + lubm("degreeFrom"), RDFS.DOMAIN, lubm("Person")))); + } + @Test + public void testAcceptRange() throws Exception { + Assert.assertTrue(Schema.isSchemaTriple(TestUtils.statement( + lubm("degreeFrom"), RDFS.RANGE, lubm("University")))); + } + @Test + public void testAcceptInverse() throws Exception { + Assert.assertTrue(Schema.isSchemaTriple(TestUtils.statement( + lubm("degreeFrom"), OWL.INVERSEOF, lubm("hasAlumnus")))); + } + + // Reject trivial schema information + @Test + public void testRejectClassAssertion() throws Exception { + Assert.assertFalse(Schema.isSchemaTriple(TestUtils.statement( + lubm("TeachingAssistant"), RDF.TYPE, OWL.CLASS))); + } + @Test + public void testRejectObjectPropertyAssertion() throws Exception { + Assert.assertFalse(Schema.isSchemaTriple(TestUtils.statement( + lubm("researchProject"), RDF.TYPE, OWL.OBJECTPROPERTY))); + } + @Test + public void testRejectDatatypePropertyAssertion() throws Exception { + Assert.assertFalse(Schema.isSchemaTriple(TestUtils.statement( + lubm("researchInterest"), RDF.TYPE, OWL.DATATYPEPROPERTY))); + } + + // Save and retrieve schema information correctly. + @Test + public void testInputSubclass() throws Exception { + Schema schema = new Schema(); + schema.processTriple(TestUtils.statement(lubm("Dean"), + RDFS.SUBCLASSOF, lubm("Professor"))); + Assert.assertTrue("Professor should be a superclass of Dean", + schema.getClass(lubm("Dean")).getSuperClasses().contains(lubm("Professor"))); + } + @Test + public void testInputDisjointClass() throws Exception { + Schema schema = new Schema(); + schema.processTriple(TestUtils.statement(SKOS.CONCEPT, + OWL.DISJOINTWITH, SKOS.COLLECTION)); + Assert.assertTrue("(x disjointWith y): y not found in x's disjoint classes", + schema.getClass(SKOS.CONCEPT).getDisjointClasses().contains(SKOS.COLLECTION)); + } + @Test + public void testInputDisjointClassReverse() throws Exception { + Schema schema = new Schema(); + schema.processTriple(TestUtils.statement(SKOS.CONCEPT, + OWL.DISJOINTWITH, SKOS.COLLECTION)); + Assert.assertTrue("(x disjointWith y): x not found in y's disjoint classes", + schema.getClass(SKOS.COLLECTION).getDisjointClasses().contains(SKOS.CONCEPT)); + } + @Test + public void testInputComplementaryClass() throws Exception { + Schema schema = new Schema(); + schema.processTriple(TestUtils.statement(TestUtils.uri("A"), + OWL.COMPLEMENTOF, TestUtils.uri("NotA"))); + Assert.assertTrue("(x complementOf y): y not found in x's complementary classes", + schema.getClass(TestUtils.uri("A")).getComplementaryClasses().contains(TestUtils.uri("NotA"))); + } + @Test + public void testInputComplementaryClassReverse() throws Exception { + Schema schema = new Schema(); + schema.processTriple(TestUtils.statement(TestUtils.uri("A"), + OWL.COMPLEMENTOF, TestUtils.uri("NotA"))); + Assert.assertTrue("(x complementOf y): x not found in y's complementary classes", + schema.getClass(TestUtils.uri("NotA")).getComplementaryClasses().contains(TestUtils.uri("A"))); + } + + @Test + public void testInputSubproperty() throws Exception { + Schema schema = new Schema(); + schema.processTriple(TestUtils.statement(lubm("worksFor"), + RDFS.SUBPROPERTYOF, lubm("memberOf"))); + Assert.assertTrue("memberOf should be a superproperty of worksFor", + schema.getProperty(lubm("worksFor")).getSuperProperties().contains(lubm("memberOf"))); + } + @Test + public void testInputDomain() throws Exception { + Schema schema = new Schema(); + schema.processTriple(TestUtils.statement(lubm("hasAlumnus"), + RDFS.DOMAIN, lubm("University"))); + Assert.assertTrue("Domain information not correctly returned", + schema.getProperty(lubm("hasAlumnus")).getDomain().contains(lubm("University"))); + } + @Test + public void testInputRange() throws Exception { + Schema schema = new Schema(); + schema.processTriple(TestUtils.statement(lubm("advisor"), RDFS.RANGE, lubm("Professor"))); + Assert.assertTrue("Range information not correctly returned", + schema.getProperty(lubm("advisor")).getRange().contains(lubm("Professor"))); + } + @Test + public void testInputInverse() throws Exception { + Schema schema = new Schema(); + schema.processTriple(TestUtils.statement(lubm("memberOf"), + OWL.INVERSEOF, lubm("memberOf"))); + Assert.assertTrue("inverseOf relation not returned", + schema.getProperty(lubm("memberOf")).getInverseProperties().contains(lubm("memberOf"))); + } + @Test + public void testInputInverseReverse() throws Exception { + Schema schema = new Schema(); + schema.processTriple(TestUtils.statement(lubm("memberOf"), + OWL.INVERSEOF, lubm("memberOf"))); + Assert.assertTrue("symmetric inverseOf relation not returned", + schema.getProperty(lubm("memberOf")).getInverseProperties().contains(lubm("memberOf"))); + } + @Test + public void testInputSymmetric() throws Exception { + Schema schema = new Schema(); + schema.processTriple(TestUtils.statement(SKOS.RELATED, + RDF.TYPE, OWL.SYMMETRICPROPERTY)); + Assert.assertTrue("Property should be identified as symmetric", + schema.getProperty(SKOS.RELATED).isSymmetric()); + } + @Test + public void testInputAsymmetric() throws Exception { + Schema schema = new Schema(); + schema.processTriple(TestUtils.statement(TestUtils.uri("hasChild"), + RDF.TYPE, OWL2.ASYMMETRICPROPERTY)); + Assert.assertTrue("Property should be identified as asymmetric", + schema.getProperty(TestUtils.uri("hasChild")).isAsymmetric()); + } + @Test + public void testInputIrreflexive() throws Exception { + Schema schema = new Schema(); + schema.processTriple(TestUtils.statement(TestUtils.uri("hasParent"), + RDF.TYPE, OWL2.IRREFLEXIVEPROPERTY)); + Assert.assertTrue("Property should be identified as irreflexive", + schema.getProperty(TestUtils.uri("hasParent")).isIrreflexive()); + } + @Test + public void testInputTransitive() throws Exception { + Schema schema = new Schema(); + schema.processTriple(TestUtils.statement(lubm("subOrganizationOf"), + RDF.TYPE, OWL.TRANSITIVEPROPERTY)); + Assert.assertTrue("Property should be identified as transitive", + schema.getProperty(lubm("subOrganizationOf")).isTransitive()); + } + @Test + public void testInputDisjointProperty() throws Exception { + Schema schema = new Schema(); + schema.processTriple(TestUtils.statement(TestUtils.uri("p1"), + OWL2.PROPERTYDISJOINTWITH, TestUtils.uri("p2"))); + Assert.assertTrue("(x propertyDisjointWith y): y not one of x's disjoint properties", + schema.getProperty(TestUtils.uri("p1")).getDisjointProperties().contains(TestUtils.uri("p2"))); + } + @Test + public void testInputDisjointPropertyReverse() throws Exception { + Schema schema = new Schema(); + schema.processTriple(TestUtils.statement(TestUtils.uri("p1"), + OWL2.PROPERTYDISJOINTWITH, TestUtils.uri("p2"))); + Assert.assertTrue("(x propertyDisjointWith y): x not one of y's disjoint properties", + schema.getProperty(TestUtils.uri("p2")).getDisjointProperties().contains(TestUtils.uri("p1"))); + } + + @Test + public void testInputOnPropertyRestriction() throws Exception { + Schema schema = new Schema(); + schema.processTriple(TestUtils.statement(TestUtils.uri("x"), + OWL.ONPROPERTY, lubm("headOf"))); + Assert.assertTrue("onProperty not returned for restriction x", + schema.getClass(TestUtils.uri("x")).getOnProperty().contains(lubm("headOf"))); + } + @Test + public void testInputOnPropertyReverse() throws Exception { + Schema schema = new Schema(); + schema.processTriple(TestUtils.statement(TestUtils.uri("x"), + OWL.ONPROPERTY, lubm("headOf"))); + Assert.assertTrue("onProperty restriction not returned given property", + schema.getProperty(lubm("headOf")).getRestrictions().contains(TestUtils.uri("x"))); + } + @Test + public void testInputSvfRestriction() throws Exception { + Schema schema = new Schema(); + schema.processTriple(TestUtils.statement(TestUtils.uri("x"), + OWL.SOMEVALUESFROM, lubm("Department"))); + Assert.assertTrue("target of someValuesFrom restriction not returned", + schema.getClass(TestUtils.uri("x")).someValuesFrom().contains(lubm("Department"))); + } + @Test + public void testInputAvfRestriction() throws Exception { + Schema schema = new Schema(); + schema.processTriple(TestUtils.statement(TestUtils.uri("x"), + OWL.ALLVALUESFROM, lubm("Department"))); + Assert.assertTrue("target of allValuesFrom restriction not returned", + schema.getClass(TestUtils.uri("x")).allValuesFrom().contains(lubm("Department"))); + } + @Test + public void testInputOnClassRestriction() throws Exception { + Schema schema = new Schema(); + schema.processTriple(TestUtils.statement(TestUtils.uri("x"), + OWL2.ONCLASS, lubm("Department"))); + Assert.assertTrue("onClass not returned for restriction x", + schema.getClass(TestUtils.uri("x")).onClass().contains(lubm("Department"))); + } + @Test + public void testInputHasValueRestriction() throws Exception { + Schema schema = new Schema(); + schema.processTriple(TestUtils.statement(TestUtils.uri("x"), + OWL.HASVALUE, TestUtils.uri("y"))); + Assert.assertTrue("hasValue not returned for restriction x", + schema.getClass(TestUtils.uri("x")).hasValue().contains(TestUtils.uri("y"))); + } + + @Test + public void testInputMaxCardinality() throws Exception { + Schema schema = new Schema(); + URI s = TestUtils.uri("x"); + URI p = OWL.MAXCARDINALITY; + schema.processTriple(TestUtils.statement(s, p, TestUtils.stringLiteral("7"))); + schema.processTriple(TestUtils.statement(s, p, TestUtils.stringLiteral("4"))); + schema.processTriple(TestUtils.statement(s, p, TestUtils.stringLiteral("-1"))); + schema.processTriple(TestUtils.statement(s, p, TestUtils.stringLiteral("3"))); + schema.processTriple(TestUtils.statement(s, p, TestUtils.stringLiteral("5"))); + Assert.assertEquals("Incorrect value returned for maxCardinality", 3, + schema.getClass(s).getMaxCardinality()); + } + + @Test + public void testInputMaxQualifiedCardinality() throws Exception { + Schema schema = new Schema(); + URI s = TestUtils.uri("x"); + URI p = OWL2.MAXQUALIFIEDCARDINALITY; + schema.processTriple(TestUtils.statement(s, p, TestUtils.stringLiteral("-20"))); + schema.processTriple(TestUtils.statement(s, p, TestUtils.stringLiteral("100"))); + schema.processTriple(TestUtils.statement(s, p, TestUtils.stringLiteral("0"))); + schema.processTriple(TestUtils.statement(s, p, TestUtils.stringLiteral("42"))); + Assert.assertEquals("Incorrect value returned for maxQualifiedCardinality", 0, + schema.getClass(s).getMaxQualifiedCardinality()); + } +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/01489efb/extras/rya.reasoning/src/test/java/mvm/rya/reasoning/TestUtils.java ---------------------------------------------------------------------- diff --git a/extras/rya.reasoning/src/test/java/mvm/rya/reasoning/TestUtils.java b/extras/rya.reasoning/src/test/java/mvm/rya/reasoning/TestUtils.java new file mode 100644 index 0000000..49c7d6d --- /dev/null +++ b/extras/rya.reasoning/src/test/java/mvm/rya/reasoning/TestUtils.java @@ -0,0 +1,79 @@ +package mvm.rya.reasoning; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import mvm.rya.api.domain.RyaStatement; +import mvm.rya.api.domain.RyaURI; + +import org.openrdf.model.BNode; +import org.openrdf.model.Literal; +import org.openrdf.model.Resource; +import org.openrdf.model.Statement; +import org.openrdf.model.URI; +import org.openrdf.model.Value; +import org.openrdf.model.ValueFactory; +import org.openrdf.model.impl.ValueFactoryImpl; +import org.openrdf.model.vocabulary.XMLSchema; + +public class TestUtils { + private static final ValueFactory VALUE_FACTORY = new ValueFactoryImpl(); + public static final String TEST_PREFIX = "http://test.test"; + public static final URI NODE = uri("http://thisnode.test", "x"); + + public static URI uri(String prefix, String u) { + if (prefix.length() > 0) { + u = prefix + "#" + u; + } + return VALUE_FACTORY.createURI(u); + } + + public static URI uri(String u) { + return uri(TEST_PREFIX, u); + } + + public static Fact fact(Resource s, URI p, Value o) { + return new Fact(s, p, o); + } + + public static Statement statement(Resource s, URI p, Value o) { + return VALUE_FACTORY.createStatement(s, p, o); + } + + public static Literal intLiteral(String s) { + return VALUE_FACTORY.createLiteral(s, XMLSchema.INT); + } + + public static Literal stringLiteral(String s) { + return VALUE_FACTORY.createLiteral(s, XMLSchema.STRING); + } + + public static Literal stringLiteral(String s, String lang) { + return VALUE_FACTORY.createLiteral(s, lang); + } + + public static BNode bnode(String id) { + return VALUE_FACTORY.createBNode(id); + } + + public static RyaStatement ryaStatement(String s, String p, String o) { + return new RyaStatement(new RyaURI(TEST_PREFIX + "#" + s), + new RyaURI(TEST_PREFIX + "#" + p), new RyaURI(TEST_PREFIX + "#" + o)); + } +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/01489efb/extras/rya.reasoning/src/test/java/mvm/rya/reasoning/mr/DuplicateEliminationTest.java ---------------------------------------------------------------------- diff --git a/extras/rya.reasoning/src/test/java/mvm/rya/reasoning/mr/DuplicateEliminationTest.java b/extras/rya.reasoning/src/test/java/mvm/rya/reasoning/mr/DuplicateEliminationTest.java new file mode 100644 index 0000000..285de79 --- /dev/null +++ b/extras/rya.reasoning/src/test/java/mvm/rya/reasoning/mr/DuplicateEliminationTest.java @@ -0,0 +1,200 @@ +package mvm.rya.reasoning.mr; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import mvm.rya.accumulo.mr.RyaStatementWritable; +import mvm.rya.api.RdfCloudTripleStoreConstants.TABLE_LAYOUT; +import mvm.rya.api.domain.RyaStatement; +import mvm.rya.api.resolver.triple.TripleRow; +import mvm.rya.api.resolver.triple.TripleRowResolver; +import mvm.rya.api.resolver.triple.impl.WholeRowTripleResolver; +import mvm.rya.reasoning.Derivation; +import mvm.rya.reasoning.OwlRule; +import mvm.rya.reasoning.Fact; +import mvm.rya.reasoning.TestUtils; + +import org.apache.accumulo.core.data.Key; +import org.apache.accumulo.core.data.Value; +import org.apache.hadoop.io.LongWritable; +import org.apache.hadoop.io.NullWritable; +import org.apache.hadoop.mrunit.mapreduce.MapDriver; +import org.apache.hadoop.mrunit.mapreduce.ReduceDriver; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openrdf.model.vocabulary.OWL; +import org.openrdf.model.vocabulary.RDF; +import org.openrdf.model.vocabulary.RDFS; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({DuplicateElimination.DuplicateEliminationReducer.class}) +public class DuplicateEliminationTest { + // inputs + static Fact X_SUB_Y = new Fact( + TestUtils.uri("x"), TestUtils.uri("subOrganizationOf"), TestUtils.uri("y")); + static Fact X_TYPE_ORG = new Fact( + TestUtils.uri("x"), RDF.TYPE, TestUtils.uri("Organization")); + static Fact X_TYPE_PERSON = new Fact( + TestUtils.uri("x"), RDF.TYPE, TestUtils.uri("Person")); + // inferences level 1 + static Fact Y_SUPER_X = new Fact( + TestUtils.uri("y"), TestUtils.uri("hasSubOrganization"), TestUtils.uri("x"), + 1, OwlRule.PRP_INV, TestUtils.uri("y")); + static Derivation X_DISJOINT = new Derivation(1, OwlRule.CAX_DW, + TestUtils.uri("x")); + // redundant inferences + static Fact X_SUB_Y_INV = new Fact( + TestUtils.uri("x"), TestUtils.uri("subOrganizationOf"), TestUtils.uri("y"), + 2, OwlRule.PRP_INV, TestUtils.uri("y")); + static Fact Y_SUPER_X_INV = new Fact( + TestUtils.uri("y"), TestUtils.uri("hasSubOrganization"), TestUtils.uri("x"), + 3, OwlRule.PRP_INV, TestUtils.uri("y")); + // schema + static Fact TRP = new Fact( + TestUtils.uri("subOrganizationOf"), RDF.TYPE, OWL.TRANSITIVEPROPERTY); + static Fact SPO = new Fact( + TestUtils.uri("subOrganizationOf"), RDFS.SUBPROPERTYOF, + TestUtils.uri("affiliatedWith")); + static Fact INV = new Fact( + TestUtils.uri("hasSubOrganization"), OWL.INVERSEOF, + TestUtils.uri("subOrganizationOf")); + static Fact DISJOINT = new Fact(TestUtils.uri("Person"), + OWL.DISJOINTWITH, TestUtils.uri("Organization")); + + @Before + public void setUp() { + Y_SUPER_X.addSource(X_SUB_Y); + X_SUB_Y_INV.addSource(Y_SUPER_X); + Y_SUPER_X_INV.addSource(X_SUB_Y_INV); + X_DISJOINT.addSource(X_TYPE_ORG); + X_DISJOINT.addSource(X_TYPE_PERSON); + } + + @Test + public void testTableMapperOutput() throws Exception { + RyaStatement rya = TestUtils.ryaStatement("x", "subOrganizationOf", "y"); + TripleRowResolver trr = new WholeRowTripleResolver(); + Map<TABLE_LAYOUT,TripleRow> map = trr.serialize(rya); + TripleRow tr = map.get(TABLE_LAYOUT.SPO); + byte[] b = new byte[0]; + Key key = new Key(tr.getRow(), tr.getColumnFamily(), + tr.getColumnQualifier(), b, 1); + Value val = new Value(b); + new MapDriver<Key, Value, Fact, Derivation>() + .withMapper(new DuplicateElimination.DuplicateTableMapper()) + .withInput(key, val) + .withOutput(X_SUB_Y, X_SUB_Y.getDerivation()) + .runTest(); + } + + @Test + public void testFileMapperOutput() throws Exception { + new MapDriver<Fact, NullWritable, Fact, Derivation>() + .withMapper(new DuplicateElimination.DuplicateFileMapper()) + .withInput(X_SUB_Y, NullWritable.get()) + .withOutput(X_SUB_Y, X_SUB_Y.getDerivation()) + .runTest(); + } + + @Test + public void testRdfMapperOutput() throws Exception { + RyaStatement rya = TestUtils.ryaStatement("x", "subOrganizationOf", "y"); + RyaStatementWritable rsw = new RyaStatementWritable(); + rsw.setRyaStatement(rya); + LongWritable l = new LongWritable(); + new MapDriver<LongWritable, RyaStatementWritable, Fact, + Derivation>() + .withMapper(new DuplicateElimination.DuplicateRdfMapper()) + .withInput(l, rsw) + .withOutput(X_SUB_Y, X_SUB_Y.getDerivation()) + .runTest(); + } + + @Test + public void testInconsistencyMapperOutput() throws Exception { + Fact empty = new Fact(); + empty.setDerivation(X_DISJOINT); + new MapDriver<Derivation, NullWritable, Fact, Derivation>() + .withMapper(new DuplicateElimination.InconsistencyMapper()) + .withInput(X_DISJOINT, NullWritable.get()) + .withOutput(empty, X_DISJOINT) + .runTest(); + } + + @Test + public void testEliminateOld() throws Exception { + List<Derivation> facts = new LinkedList<>(); + facts.add(X_SUB_Y_INV.getDerivation()); + facts.add(X_SUB_Y.getDerivation()); + X_SUB_Y.unsetDerivation(); + ReduceDriver<Fact, Derivation, Fact, NullWritable> driver = new ReduceDriver<>(); + driver.getConfiguration().setInt(MRReasoningUtils.STEP_PROP, 1); + driver.withReducer(new DuplicateElimination.DuplicateEliminationReducer()) + .withInput(X_SUB_Y, facts) + .runTest(); + } + + @Test + public void testRetainSimplest() throws Exception { + List<Derivation> facts = new LinkedList<>(); + facts.add(Y_SUPER_X_INV.getDerivation()); + facts.add(Y_SUPER_X.getDerivation()); + Fact unset = Y_SUPER_X.clone(); + unset.unsetDerivation(); + ReduceDriver<Fact, Derivation, Fact, NullWritable> driver = new ReduceDriver<>(); + driver.getConfiguration().setInt(MRReasoningUtils.STEP_PROP, 1); + driver.withReducer(new DuplicateElimination.DuplicateEliminationReducer()) + .withInput(unset, facts) + .withMultiOutput(MRReasoningUtils.INTERMEDIATE_OUT, + Y_SUPER_X, NullWritable.get()) + .runTest(); + } + + @Test + public void testInconsistencyReduce() throws Exception { + List<Derivation> facts = new LinkedList<>(); + facts.add(X_DISJOINT.clone()); + facts.add(X_DISJOINT.clone()); + ReduceDriver<Fact, Derivation, Fact, NullWritable> driver = new ReduceDriver<>(); + driver.getConfiguration().setInt(MRReasoningUtils.STEP_PROP, 1); + driver.withReducer(new DuplicateElimination.DuplicateEliminationReducer()) + .withInput(Fact.NONE, facts) + .withMultiOutput(MRReasoningUtils.INCONSISTENT_OUT, + X_DISJOINT, NullWritable.get()) + .runTest(); + } + + @Test + public void testInconsistencyOld() throws Exception { + List<Derivation> facts = new LinkedList<>(); + facts.add(X_DISJOINT.clone()); + ReduceDriver<Fact, Derivation, Fact, NullWritable> driver = new ReduceDriver<>(); + driver.getConfiguration().setInt(MRReasoningUtils.STEP_PROP, 2); + driver.withReducer(new DuplicateElimination.DuplicateEliminationReducer()) + .withInput(Fact.NONE, facts) + .runTest(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/01489efb/extras/rya.reasoning/src/test/java/mvm/rya/reasoning/mr/ForwardChainTest.java ---------------------------------------------------------------------- diff --git a/extras/rya.reasoning/src/test/java/mvm/rya/reasoning/mr/ForwardChainTest.java b/extras/rya.reasoning/src/test/java/mvm/rya/reasoning/mr/ForwardChainTest.java new file mode 100644 index 0000000..2be680b --- /dev/null +++ b/extras/rya.reasoning/src/test/java/mvm/rya/reasoning/mr/ForwardChainTest.java @@ -0,0 +1,250 @@ +package mvm.rya.reasoning.mr; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import mvm.rya.accumulo.mr.RyaStatementWritable; +import mvm.rya.api.RdfCloudTripleStoreConstants.TABLE_LAYOUT; +import mvm.rya.api.domain.RyaStatement; +import mvm.rya.api.resolver.triple.TripleRow; +import mvm.rya.api.resolver.triple.TripleRowResolver; +import mvm.rya.api.resolver.triple.impl.WholeRowTripleResolver; +import mvm.rya.reasoning.OwlRule; +import mvm.rya.reasoning.Fact; +import mvm.rya.reasoning.Schema; +import mvm.rya.reasoning.TestUtils; + +import org.apache.accumulo.core.data.Key; +import org.apache.accumulo.core.data.Value; +import org.apache.hadoop.io.LongWritable; +import org.apache.hadoop.io.NullWritable; +import org.apache.hadoop.mrunit.mapreduce.MapDriver; +import org.apache.hadoop.mrunit.mapreduce.ReduceDriver; +import org.apache.hadoop.mrunit.mapreduce.ReduceFeeder; +import org.apache.hadoop.mrunit.types.KeyValueReuseList; +import org.apache.hadoop.mrunit.types.Pair; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openrdf.model.URI; +import org.openrdf.model.vocabulary.OWL; +import org.openrdf.model.vocabulary.RDF; +import org.openrdf.model.vocabulary.RDFS; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ForwardChain.FileMapper.class, ForwardChain.ReasoningReducer.class}) +public class ForwardChainTest { + // inputs + static Fact X_SUB_Y = new Fact( + TestUtils.uri("x"), TestUtils.uri("subOrganizationOf"), TestUtils.uri("y")); + static Fact Y_SUB_Z = new Fact( + TestUtils.uri("y"), TestUtils.uri("subOrganizationOf"), TestUtils.uri("z")); + // inferences + static Fact Y_SUPER_X = new Fact( + TestUtils.uri("y"), TestUtils.uri("hasSubOrganization"), TestUtils.uri("x"), + 1, OwlRule.PRP_INV, TestUtils.uri("y")); + static Fact X_SUB_Z = new Fact( + TestUtils.uri("x"), TestUtils.uri("subOrganizationOf"), TestUtils.uri("z"), + 1, OwlRule.PRP_TRP, TestUtils.uri("y")); + // schema + static Fact TRP = new Fact( + TestUtils.uri("subOrganizationOf"), RDF.TYPE, OWL.TRANSITIVEPROPERTY); + static Fact SPO = new Fact( + TestUtils.uri("subOrganizationOf"), RDFS.SUBPROPERTYOF, + TestUtils.uri("affiliatedWith")); + static Fact INV = new Fact( + TestUtils.uri("hasSubOrganization"), OWL.INVERSEOF, + TestUtils.uri("subOrganizationOf")); + + Schema schema; + + @Before + public void setUp() { + schema = new Schema(); + schema.processTriple(TRP.getTriple()); + schema.closure(); + Y_SUPER_X.addSource(X_SUB_Y); + X_SUB_Z.addSource(X_SUB_Y); + X_SUB_Z.addSource(Y_SUB_Z); + } + + @Test + public void testTableMapperOutput() throws Exception { + RyaStatement rya = TestUtils.ryaStatement("x", "subOrganizationOf", "y"); + TripleRowResolver trr = new WholeRowTripleResolver(); + Map<TABLE_LAYOUT,TripleRow> map = trr.serialize(rya); + TripleRow tr = map.get(TABLE_LAYOUT.SPO); + byte[] b = new byte[0]; + Key key = new Key(tr.getRow(), tr.getColumnFamily(), + tr.getColumnQualifier(), b, 1); + Value val = new Value(b); + ResourceWritable rw1 = new ResourceWritable(); + ResourceWritable rw2 = new ResourceWritable(); + rw1.set(TestUtils.uri("x")); + rw2.set(TestUtils.uri("y")); + new MapDriver<Key, Value, ResourceWritable, Fact>() + .withMapper(new ForwardChain.TableMapper(schema)) + .withInput(key, val) + .withOutput(rw1, X_SUB_Y) + .withOutput(rw2, X_SUB_Y) + .runTest(); + } + + @Test + public void testFileMapperOutput() throws Exception { + ResourceWritable rw1 = new ResourceWritable(); + ResourceWritable rw2 = new ResourceWritable(); + rw1.set(TestUtils.uri("x")); + rw2.set(TestUtils.uri("y")); + new MapDriver<Fact, NullWritable, ResourceWritable, Fact>() + .withMapper(new ForwardChain.FileMapper(schema)) + .withInput(X_SUB_Y, NullWritable.get()) + .withOutput(rw1, X_SUB_Y) + .withOutput(rw2, X_SUB_Y) + .runTest(); + } + + @Test + public void testRdfMapperOutput() throws Exception { + RyaStatement rya = TestUtils.ryaStatement("x", "subOrganizationOf", "y"); + RyaStatementWritable rsw = new RyaStatementWritable(); + rsw.setRyaStatement(rya); + LongWritable l = new LongWritable(); + ResourceWritable rw1 = new ResourceWritable(); + ResourceWritable rw2 = new ResourceWritable(); + rw1.set(TestUtils.uri("x")); + rw2.set(TestUtils.uri("y")); + new MapDriver<LongWritable, RyaStatementWritable, ResourceWritable, + Fact>() + .withMapper(new ForwardChain.RdfMapper(schema)) + .withInput(l, rsw) + .withOutput(rw1, X_SUB_Y) + .withOutput(rw2, X_SUB_Y) + .runTest(); + } + + @Test + public void testReducerInference() throws Exception { + schema.processTriple(INV.getTriple()); + schema.closure(); + ResourceWritable rw = new ResourceWritable(); + rw.set(TestUtils.uri("y")); + List<Fact> facts = new LinkedList<>(); + facts.add(X_SUB_Y); + new ReduceDriver<ResourceWritable, Fact, Fact, NullWritable>() + .withReducer(new ForwardChain.ReasoningReducer(schema)) + .withInput(rw, facts) + .withMultiOutput(MRReasoningUtils.INTERMEDIATE_OUT, + Y_SUPER_X, NullWritable.get()) + .runTest(); + } + + @Test + public void testReducerJoin() throws Exception { + ResourceWritable rw = new ResourceWritable(); + rw.set(TestUtils.uri("y")); + List<Fact> facts = new LinkedList<>(); + facts.add(X_SUB_Y); + facts.add(Y_SUB_Z); + ReduceDriver<ResourceWritable, Fact, Fact, + NullWritable> driver = new ReduceDriver<>(); + driver.getConfiguration().setInt(MRReasoningUtils.STEP_PROP, 1); + driver.withReducer(new ForwardChain.ReasoningReducer(schema)) + .withInput(rw, facts) + .withMultiOutput(MRReasoningUtils.INTERMEDIATE_OUT, + X_SUB_Z, NullWritable.get()) + .runTest(); + } + + /** + * MultipleOutputs support is minimal, so we have to check each map/reduce + * step explicitly + */ + @Test + public void testTransitiveChain() throws Exception { + int max = 8; + int n = 4; + URI prop = TestUtils.uri("subOrganizationOf"); + Map<Integer, Map<Integer, Pair<Fact, NullWritable>>> connections + = new HashMap<>(); + for (int i = 0; i <= max; i++) { + connections.put(i, new HashMap<Integer, Pair<Fact, NullWritable>>()); + } + // Initial input: make a chain from org0 to org8 + for (int i = 0; i < max; i++) { + URI orgI = TestUtils.uri("org" + i); + URI orgJ = TestUtils.uri("org" + (i + 1)); + Fact triple = new Fact(orgI, prop, orgJ); + connections.get(i).put(i+1, new Pair<>(triple, NullWritable.get())); + } + for (int i = 1; i <= n; i++) { + // Map: + MapDriver<Fact, NullWritable, ResourceWritable, + Fact> mDriver = new MapDriver<>(); + mDriver.getConfiguration().setInt(MRReasoningUtils.STEP_PROP, i); + mDriver.setMapper(new ForwardChain.FileMapper(schema)); + for (int j : connections.keySet()) { + for (int k : connections.get(j).keySet()) { + mDriver.addInput(connections.get(j).get(k)); + } + } + List<Pair<ResourceWritable, Fact>> mapped = mDriver.run(); + // Convert data for reduce phase: + ReduceFeeder<ResourceWritable, Fact> feeder = + new ReduceFeeder<>(mDriver.getConfiguration()); + List<KeyValueReuseList<ResourceWritable, Fact>> intermediate + = feeder.sortAndGroup(mapped, + new ResourceWritable.SecondaryComparator(), + new ResourceWritable.PrimaryComparator()); + // Reduce, and compare to expected output: + ReduceDriver<ResourceWritable, Fact, Fact, + NullWritable> rDriver = new ReduceDriver<>(); + rDriver.getConfiguration().setInt(MRReasoningUtils.STEP_PROP, i); + rDriver.setReducer(new ForwardChain.ReasoningReducer(schema)); + rDriver.addAllElements(intermediate); + int maxSpan = (int) Math.pow(2, i); + int minSpan = (maxSpan/2) + 1; + // For each j, build all paths starting with j: + for (int j = 0; j < max; j++) { + // This includes any path of length k for appropriate k: + for (int k = minSpan; k <= maxSpan && j+k <= max; k++) { + int middle = j + minSpan - 1; + URI left = TestUtils.uri("org" + j); + URI right = TestUtils.uri("org" + (j + k)); + Fact triple = new Fact(left, prop, + right, i, OwlRule.PRP_TRP, TestUtils.uri("org" + middle)); + triple.addSource(connections.get(j).get(middle).getFirst()); + triple.addSource(connections.get(middle).get(j+k).getFirst()); + Pair<Fact, NullWritable> expected = + new Pair<>(triple, NullWritable.get()); + connections.get(j).put(j+k, expected); + rDriver.addMultiOutput("intermediate", expected); + } + } + rDriver.runTest(); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/01489efb/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index ad0e960..ac887b4 100644 --- a/pom.xml +++ b/pom.xml @@ -107,6 +107,7 @@ under the License. <mockito.version>1.10.19</mockito.version> <!-- Newest: 1.10.19 --> <mrunit.version>1.1.0</mrunit.version> <!-- Newest: 1.1.0 --> <slf4j.version>1.6.6</slf4j.version> <!-- Newest: 1.7.13 --> + <powermock.version>1.6.1</powermock.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> @@ -524,6 +525,19 @@ under the License. <version>${mrunit.version}</version> <classifier>hadoop2</classifier> <scope>test</scope> + <!-- mrunit includes incompatible versions of powermock and junit by default --> + <exclusions> + <exclusion> + <groupId>org.powermock</groupId> + <artifactId>powermock-module-junit4</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-module-junit4</artifactId> + <version>${powermock.version}</version> + <scope>test</scope> </dependency> </dependencies> </dependencyManagement>
