All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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