com.bigdata.rdf.rules.FastClosure Maven / Gradle / Ivy
package com.bigdata.rdf.rules;
import java.util.LinkedList;
import java.util.List;
import org.openrdf.model.vocabulary.OWL;
import com.bigdata.bop.IBindingSet;
import com.bigdata.bop.IConstant;
import com.bigdata.bop.IConstraint;
import com.bigdata.bop.IVariable;
import com.bigdata.bop.bindingSet.EmptyBindingSet;
import com.bigdata.bop.constraint.Constraint;
import com.bigdata.bop.constraint.NEConstant;
import com.bigdata.rdf.internal.IV;
import com.bigdata.rdf.store.AbstractTripleStore;
import com.bigdata.relation.rule.IRule;
import com.bigdata.relation.rule.Rule;
/**
* Fast forward closure of the store based on "An approach to RDF(S)
* Query, Manipulation and Inference on Databases" by Lu, Yu, Tu, Lin, and Zhang.
*
* @author Bryan Thompson
* @version $Id$
*/
public class FastClosure extends BaseClosure {
public FastClosure(AbstractTripleStore db) {
super( db );
}
public MappedProgram getProgram(String db, String focusStore) {
/*
* Note: The steps below are numbered with regard to the paper cited
* in the javadoc above.
*
* Most steps presume that the computed entailments have been added
* to the database (vs the temp store).
*/
final MappedProgram program = new MappedProgram("fastForwardClosure",
focusStore, false/* parallel */, false/* closure */);
if (!rdfsOnly) {
// owl:equivalentProperty
if (forwardChainOwlEquivalentProperty) {
program.addClosureOf(new RuleOwlEquivalentProperty(db,
vocab));
}
}
/*
* @todo The P,D,R,C, and T collections could be utilized to generate
* sub-programs appearing in their respective places in the overall
* sequential execution of the fast closure program and those
* sub-programs could generate [NAMED RESULT SETS] that were then
* accessed by later steps in the program and auto-magically dropped
* when the program was finished. (Currently, a Callable exists that
* directly generates the P,D,R,C or T set and then consumes that set
* producing the appropriate entailments - vocab is efficient because
* each result is used only by a single set vs being reused by multiple
* steps).
*/
{
// // 2. Compute P (the set of possible sub properties).
// final Set P = getSubProperties(focusStore, database);
// 3. (?x, P, ?y) -> (?x, rdfs:subPropertyOf, ?y)
program.addStep(new RuleFastClosure3(db,focusStore,vocab));//, P));
}
// 4. RuleRdfs05 until fix point (rdfs:subPropertyOf closure).
program.addClosureOf(new IRule[] { new RuleRdfs05(db, vocab) });
// 4a. Obtain: D,R,C,T.
// final Set D = getSubPropertiesOf(focusStore, database, rdfsDomain.get());
// final Set R = getSubPropertiesOf(focusStore, database, rdfsRange.get());
// final Set C = getSubPropertiesOf(focusStore, database, rdfsSubClassOf.get());
// final Set T = getSubPropertiesOf(focusStore, database, rdfType.get());
{
/*
* Note: steps 5 and 6 are executed in parallel since they have no
* mutual dependency.
*/
final MappedProgram subProgram = new MappedProgram("fastClosure{5 6}",
focusStore, true/* parallel */, false/* closure */);
// 5. (?x, D, ?y ) -> (?x, rdfs:domain, ?y)
subProgram.addStep(new RuleFastClosure5(db,focusStore,vocab));//, D));
// 6. (?x, R, ?y ) -> (?x, rdfs:range, ?y)
subProgram.addStep(new RuleFastClosure6(db,focusStore,vocab));//, R));
program.addStep(subProgram);
}
if (!rdfsOnly) {
// owl:equivalentClass
if (forwardChainOwlEquivalentClass) {
program.addClosureOf(new RuleOwlEquivalentClass(db, vocab));
}
}
// 7. (?x, C, ?y ) -> (?x, rdfs:subClassOf, ?y)
{
program.addStep(new RuleFastClosure7(db,focusStore,vocab));//, C));
}
// 8. RuleRdfs11 until fix point (rdfs:subClassOf closure).
program.addClosureOf(new RuleRdfs11(db, vocab));
// 9. (?x, T, ?y ) -> (?x, rdf:type, ?y)
{
program.addStep(new RuleFastClosure9(db,focusStore,vocab));//, T));
}
// 10. RuleRdfs02
program.addStep(new RuleRdfs02(db, vocab));
/*
* 11. special rule w/ 3-part antecedent.
*
* (?x, ?y, ?z), (?y, rdfs:subPropertyOf, ?a), (?a, rdfs:domain, ?b) ->
* (?x, rdf:type, ?b).
*/
program.addStep(new RuleFastClosure11(db, vocab));
// 12. RuleRdfs03
program.addStep(new RuleRdfs03(db, vocab));
/*
* 13. special rule w/ 3-part antecedent.
*
* (?x, ?y, ?z), (?y, rdfs:subPropertyOf, ?a), (?a, rdfs:range, ?b ) ->
* (?x, rdf:type, ?b )
*/
program.addStep(new RuleFastClosure13(db, vocab));
if (forwardChainRdfTypeRdfsResource) {
/*
* 14-15. These steps correspond to rdfs4a and rdfs4b and generate
* (?x rdf:type rdfs:Resource) entailments. We execute these steps
* iff we are storing those entailments.
*/
// 14-15. RuleRdf04
MappedProgram subProgram = new MappedProgram("rdfs04", focusStore,
true/* parallel */, false/* closure */);
subProgram.addStep(new RuleRdfs04a(db, vocab));
subProgram.addStep(new RuleRdfs04b(db, vocab));
program.addStep(subProgram);
}
// 16. RuleRdf01
program.addStep(new RuleRdf01(db, vocab));
// 17. RuleRdfs09
program.addStep(new RuleRdfs09(db, vocab));
// 18. RuleRdfs10
program.addStep(new RuleRdfs10(db, vocab));
// 19. RuleRdfs08.
program.addStep(new RuleRdfs08(db, vocab));
// 20. RuleRdfs13.
program.addStep(new RuleRdfs13(db, vocab));
// 21. RuleRdfs06.
program.addStep(new RuleRdfs06(db, vocab));
// 22. RuleRdfs07.
program.addStep(new RuleRdfs07(db, vocab));
if (!rdfsOnly) {
{
/*
* Combines the rules into a set and computes the closure of
* that set.
*/
final List tmp = new LinkedList();
if (forwardChainOwlTransitiveProperty) {
tmp.add(new RuleOwlTransitiveProperty1(db, vocab));
// tmp.add(new RuleOwlTransitiveProperty2(db, vocab));
}
if (forwardChainOwlInverseOf) {
tmp.add(new RuleOwlInverseOf1(db, vocab));
tmp.add(new RuleOwlInverseOf2(db, vocab));
}
if (forwardChainOwlHasValue) {
tmp.add(new RuleOwlHasValue(db, vocab));
}
if (forwardChainOwlSymmetricProperty) {
tmp.add(new RuleOwlSymmetricProperty(db, vocab));
}
if (enableOwlFunctionalAndInverseFunctionalProperty) {
tmp.add(new RuleOwlFunctionalProperty(db, vocab));
tmp.add(new RuleOwlInverseFunctionalProperty(db, vocab));
}
// add the custom rules
tmp.addAll(getCustomRules(db));
if (!tmp.isEmpty()) {
/*
* Fix point whatever set of rules were selected above.
*/
program.addClosureOf(tmp.toArray(new IRule[] {}));
}
}
// owl:sameAs
if (forwardChainOwlSameAsClosure) {
final IConstant owlSameAs = vocab.getConstant(OWL.SAMEAS);
// reflexive closure over owl:sameAs.
program.addClosureOf(new RuleOwlSameAs1(db, vocab));
// transitive closure over owl:sameAs.
program.addClosureOf(new RuleOwlSameAs1b(db, vocab));
if (forwardChainOwlSameAsProperties) {
/*
* Apply properties.
*
* Note: owl:sameAs2,3 should exclude matches where the
* predicate in the head is owl:sameAs. This case is already
* covered by rules owl:sameas {1, 1b}. We specialize the
* rules here since we also use 2 and 3 in the full forward
* closure where all rules are brought to fix point together
* and we do NOT want to make that exclusion in that case.
*/
// empty binding set since we only specialize the
// constraints.
final IBindingSet noBindings = EmptyBindingSet.INSTANCE;//new ArrayBindingSet(0/* capacity */);
{
final Rule tmp = new RuleOwlSameAs2(db, vocab);
// the variable in the predicate position of the head of
// the rule.
final IVariable p = (IVariable) tmp
.getHead().get(1/* p */);
program.addStep(tmp.specialize(//
noBindings,//
new IConstraint[] { //
Constraint.wrap(new NEConstant(p, owlSameAs)) //
}//
));
}
{
final Rule tmp = new RuleOwlSameAs3(db, vocab);
// the variable in the predicate position of the head of
// the rule.
final IVariable p = (IVariable) tmp
.getHead().get(1/* p */);
program.addStep(tmp.specialize(//
noBindings,//
new IConstraint[] { //
Constraint.wrap(new NEConstant(p, owlSameAs)) //
}//
));
}
}
}
}
return program;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy