Repository: incubator-rya
Updated Branches:
  refs/heads/develop 8ac8b394a -> 01489efb3


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>

Reply via email to