/**
Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved.
Contact:
SYSTAP, LLC DBA Blazegraph
2501 Calvert ST NW #106
Washington, DC 20008
licenses@blazegraph.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Created on Oct 26, 2007
*/
package com.bigdata.relation.rule;
import java.util.Set;
import com.bigdata.bop.Constant;
import com.bigdata.bop.IBindingSet;
import com.bigdata.bop.IConstant;
import com.bigdata.bop.IConstraint;
import com.bigdata.bop.IPredicate;
import com.bigdata.bop.IVariable;
import com.bigdata.bop.Var;
import com.bigdata.bop.bindingSet.HashBindingSet;
import com.bigdata.bop.bindingSet.ListBindingSet;
import com.bigdata.rdf.internal.IV;
import com.bigdata.rdf.internal.VTE;
import com.bigdata.rdf.spo.SPOKeyOrder;
import com.bigdata.test.MockTermIdFactory;
/**
* Test suite for basic {@link Rule} mechanisms.
*
* @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan Thompson</a>
* @version $Id$
*/
public class TestRule extends AbstractRuleTestCase {
/**
*
*/
public TestRule() {
super();
}
/**
* @param name
*/
public TestRule(String name) {
super(name);
}
private final String relation = "test";
/**
* Verify constructor of a simple rule.
*/
public void test_ctor() {
final Var<IV> u = Var.var("u");
final IRule r = new MyRule(
// head
new P(relation, u, rdfsSubClassOf, rdfsResource),
// tail
new IPredicate[] {//
new P(relation, u, rdfType, rdfsClass) //
}
);
// write out the rule on the console.
System.err.println(r.toString());
assertEquals("variableCount", 1, r.getVariableCount());
// {
//
// final IPredicate<?> tmp = new P(relation, u, rdfsSubClassOf,
// rdfsResource);
//
// final IPredicate<?> head = r.getHead();
//
// assertTrue("head", tmp.equals(head));
//
// }
// assertTrue("tail[0]", new P(relation, u, rdfType, rdfsClass).equals(r
// .getTail(0)));
assertSameIteratorAnyOrder(new Comparable[] { u }, r.getVariables());
assertTrue(r.isDeclared(u));
assertFalse(r.isDeclared(Var.var("x")));
{
final IBindingSet bindings = new HashBindingSet();
assertFalse(r.getTail(0).isFullyBound(SPOKeyOrder.SPO));
// assertFalse(r.getTail(0).isFullyBound(SPOKeyOrder.SPOC));
assertEquals(1, r.getTail(0).getVariableCount(SPOKeyOrder.SPO));
// assertEquals(2, r.getTail(0).getVariableCount(SPOKeyOrder.SPOC));
assertFalse(r.isFullyBound(0, bindings));
assertEquals(1, r.getVariableCount(0,bindings));
bindings.set(u, rdfType);
assertTrue(r.isFullyBound(0, bindings));
assertEquals(0, r.getVariableCount(0,bindings));
}
}
public void test_ctor_noHead() {
final Var<IV> u = Var.var("u");
final IRule r = new MyRule(
// NO head
null,
// tail
new IPredicate[] {//
new P(relation, u, rdfType, rdfsClass) //
});
// write out the rule on the console.
System.err.println(r.toString());
assertEquals("variableCount", 1, r.getVariableCount());
assertNull("head", r.getHead());
// assertTrue("tail[0]", new P(relation, u, rdfType, rdfsClass).equals(r
// .getTail(0)));
assertSameIteratorAnyOrder(new Comparable[] { u }, r.getVariables());
assertTrue(r.isDeclared(u));
assertFalse(r.isDeclared(Var.var("x")));
}
/**
* Test for computing the intersection of the variables in two predicates.
*/
public void test_getSharedVars() {
final IPredicate p1 = new P(relation,//
Var.var("u"), rdfsSubClassOf, rdfsResource);
final IPredicate p2 = new P(relation,//
Var.var("x"), rdfType, Var.var("u"));
final Set<IVariable<?>> actual = Rule.getSharedVars(p1, p2);
assertEquals(1, actual.size());
assertTrue(actual.contains(Var.var("u")));
}
/**
* Test the ability to compute the variables shared between two {@link Pred}s
* in a {@link Rule}.
*/
public void test_getSharedVarsInTail() {
final IRule r = new TestRuleRdfs9(relation);
final Set<IVariable> shared = r.getSharedVars(0, 1);
assertTrue(shared.contains(Rule.var("u")));
assertFalse(shared.contains(Rule.var("v")));
assertEquals(1,shared.size());
}
/**
* Verify variable binding stuff for a rule.
*/
public void test_ruleBindings() {
final MockTermIdFactory factory = new MockTermIdFactory();
final Var<IV> u = Var.var("u");
final IPredicate head = new P(relation, u, rdfsSubClassOf, rdfsResource);
final IPredicate[] body = new IPredicate[] {//
new P(relation, u, rdfType, rdfsClass)//
};
final IRule r = new MyRule(head, body);
final IBindingSet bindingSet = new HashBindingSet();
// verify body[0] is not fully bound.
assertFalse(r.isFullyBound(0,bindingSet));
// verify you can overwrite a variable in the tail.
bindingSet.set(u, new Constant<IV>(factory.newTermId(VTE.URI)));
assertTrue(r.isFullyBound(0,bindingSet)); // is fully bound.
bindingSet.clearAll(); // restore the bindings.
assertFalse(r.isFullyBound(0,bindingSet)); // no longer fully bound.
}
/**
* Verify that constraint violations are being tested (specific
* {@link IConstraint}s are tested elsewhere).
*/
public void test_constraints() {
/*
* (?u,rdfs:subClassOf,?x), (?v,rdf:type,?u) -> (?v,rdf:type,?x)
*
* Note: u != x
*/
final IRule r = new TestRuleRdfs9(relation);
final IBindingSet bindingSet = new HashBindingSet();
// final IBindingSet bindingSet = new ArrayBindingSet(3);
final IVariable u = Var.var("u");
final IVariable x = Var.var("x");
// set a binding
bindingSet.set(u, rdfsClass);
if (log.isInfoEnabled()) {
log.info(bindingSet.toString());
log.info(r.toString(bindingSet));
}
// verify bindings are Ok.
assertTrue(r.isConsistent(bindingSet));
/*
* Now try to bind [x] to a different constant with a different value
* and verify no violation is detected.
*/
bindingSet.set(x, rdfsResource);
if (log.isInfoEnabled()) {
log.info(bindingSet.toString());
log.info(r.toString(bindingSet));
}
// verify bindings are Ok.
assertTrue(r.isConsistent(bindingSet));
/*
* Now try to re-bind [x] to the same constant as [u] and verify that
* the violation of the [u != x] constraint is detected.
*/
bindingSet.set(x, rdfsClass);
if (log.isInfoEnabled()) {
log.info(bindingSet.toString());
log.info(r.toString(bindingSet));
}
// verify bindings are illegal.
assertFalse(r.isConsistent(bindingSet));
/*
* Now try to bind [x] to a distinct constant having the same value and
* verify that the violation of the [u != x] constraint is detected.
*/
// spot check equals() for the Constant.
assertTrue(rdfsClass.equals(new Constant<IV>(rdfsClass.get())));
// re-bind [x].
bindingSet.set(x, new Constant<IV>(rdfsClass.get()));
if (log.isInfoEnabled()) {
log.info(bindingSet.toString());
log.info(r.toString(bindingSet));
}
// verify bindings are illegal.
assertFalse(r.isConsistent(bindingSet));
/*
* Clear the binding for [u] and verify that the bindings are then legal.
*/
bindingSet.clear(u);
if (log.isInfoEnabled()) {
log.info(bindingSet.toString());
log.info(r.toString(bindingSet));
}
// verify bindings are Ok.
assertTrue(r.isConsistent(bindingSet));
}
/**
* Test case for specializing a rule by binding some of its variables.
*
* @todo test adding constraints.
*/
public void test_specializeRule() {
// (?u,rdfs:subClassOf,?x), (?v,rdf:type,?u) -> (?v,rdf:type,?x)
final IRule r = new TestRuleRdfs9(relation);
if (log.isInfoEnabled())
log.info(r.toString());
{
/*
* Verify we can override a variable with a constant.
*/
final IBindingSet bindingSet = new ListBindingSet(//
new IVariable[] { Var.var("v") },//
new IConstant[] { rdfProperty }//
);
final IRule r1 = r
.specialize("r1", bindingSet, new IConstraint[] {});
if (log.isInfoEnabled())
log.info(r1.toString());
// verify "v" bound in body[1].
assertTrue(r1.getTail(1).get(0).isConstant());
assertTrue(rdfProperty.equals(r1.getTail(1).get(0)));
}
{
/*
* Verify we can override another variable with a constant.
*/
final IBindingSet bindingSet = new ListBindingSet(//
new IVariable[] { Var.var("x") },//
new IConstant[] { rdfProperty }//
);
final IRule r2 = r
.specialize("r2", bindingSet, new IConstraint[] {});
if (log.isInfoEnabled())
log.info(r2.toString());
// verify "x" bound in body[0].
assertTrue(r2.getTail(0).get(2).isConstant());
assertTrue(rdfProperty.equals(r2.getTail(0).get(2)));
}
}
}