Package org.semweb4j.sesame

Source Code of org.semweb4j.sesame.ForwardChainingRDFSPlusInverseInferencerConnection

/*
* Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2007.
*
* Copyright FZI (http://fzi.de), (c) 2007-2008.
*
* Licensed under the Aduna/FZI BSD-style license.
*/
package org.semweb4j.sesame;

import java.util.Iterator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import info.aduna.iteration.CloseableIteration;
import info.aduna.iteration.Iterations;
import info.aduna.text.ASCIIUtil;

import org.openrdf.model.Graph;
import org.openrdf.model.Resource;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.impl.GraphImpl;
import org.openrdf.model.impl.URIImpl;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.sail.Sail;
import org.openrdf.sail.SailConnectionListener;
import org.openrdf.sail.SailException;
import org.openrdf.sail.inferencer.InferencerConnection;
import org.openrdf.sail.inferencer.InferencerConnectionWrapper;

/**
* Forward-chaining RDF Schema inferencer, using the rules from the <a
* href="http://www.w3.org/TR/2004/REC-rdf-mt-20040210/">RDF Semantics
* Recommendation (10 February 2004)</a>. This inferencer can be used to add
* RDF Schema semantics to any Sail that returns {@link InferencerConnection}s
* from their {@link Sail#getConnection()} method.
*
* Added: nrl:inverse
*
* @author voelkel
*/
class ForwardChainingRDFSPlusInverseInferencerConnection extends InferencerConnectionWrapper implements
    SailConnectionListener
{

  /*-----------*
   * Constants *
   *-----------*/

  protected final Logger logger = LoggerFactory.getLogger(this.getClass());

  /*-----------*
   * Variables *
   *-----------*/

  /**
   * true if the base Sail reported removed statements.
   */
  private boolean statementsRemoved;

  /**
   * Contains the statements that have been reported by the base Sail as
   */
  private Graph newStatements;

  private Graph newThisIteration;

  /**
   * Flags indicating which rules should be evaluated.
   */
  private boolean[] checkRule = new boolean[RDFSPlusInversesRules.RULECOUNT];

  /**
   * Flags indicating which rules should be evaluated next iteration.
   */
  private boolean[] checkRuleNextIter = new boolean[RDFSPlusInversesRules.RULECOUNT];

  private int totalInferred = 0;

  /**
   * The number of inferred statements per rule.
   */
  private int[] ruleCount = new int[RDFSPlusInversesRules.RULECOUNT];

  /*--------------*
   * Constructors *
   *--------------*/

  public ForwardChainingRDFSPlusInverseInferencerConnection(InferencerConnection con) {
    super(con);
    con.addConnectionListener(this);
  }

  /*---------*
   * Methods *
   *---------*/

  // Called by base sail
  public void statementAdded(Statement st) {
    if (this.statementsRemoved) {
      // No need to record, starting from scratch anyway
      return;
    }

    if (this.newStatements == null) {
      this.newStatements = new GraphImpl();
    }
    this.newStatements.add(st);
  }

  // Called by base sail
  public void statementRemoved(@SuppressWarnings("unused")
  Statement st) {
    this.statementsRemoved = true;
    this.newStatements = null;
  }

  @Override
  public void flushUpdates()
    throws SailException
  {
    super.flushUpdates();

    if (this.statementsRemoved) {
      this.logger.debug("statements removed, starting inferencing from scratch");
      clearInferred();
      addAxiomStatements();

      this.newStatements = new GraphImpl();
      Iterations.addAll(getWrappedConnection().getStatements(null, null, null, true), this.newStatements);

      this.statementsRemoved = false;
    }

    doInferencing();
  }

  @Override
  public void rollback()
    throws SailException
  {
    this.statementsRemoved = false;
    this.newStatements = null;

    super.rollback();
  }
 
 
  public static final String NRL_NS = "http://www.semanticdesktop.org/ontologies/2007/08/15/nrl#";
 
  public static final URI NRL_InverseProperty = new URIImpl(NRL_NS+"inverseProperty");

  /**
   * Adds all basic set of axiom statements from which the complete set can be
   * inferred to the underlying Sail.
   */
  protected void addAxiomStatements()
    throws SailException
  {
    this.logger.debug("Inserting axiom statements");

    // RDF axiomatic triples (from RDF Semantics, section 3.1):

    addInferredStatement(RDF.TYPE, RDF.TYPE, RDF.PROPERTY);
    addInferredStatement(RDF.SUBJECT, RDF.TYPE, RDF.PROPERTY);
    addInferredStatement(RDF.PREDICATE, RDF.TYPE, RDF.PROPERTY);
    addInferredStatement(RDF.OBJECT, RDF.TYPE, RDF.PROPERTY);

    addInferredStatement(RDF.FIRST, RDF.TYPE, RDF.PROPERTY);
    addInferredStatement(RDF.REST, RDF.TYPE, RDF.PROPERTY);
    addInferredStatement(RDF.VALUE, RDF.TYPE, RDF.PROPERTY);

    addInferredStatement(RDF.NIL, RDF.TYPE, RDF.LIST);

    // RDFS axiomatic triples (from RDF Semantics, section 4.1):

    addInferredStatement(RDF.TYPE, RDFS.DOMAIN, RDFS.RESOURCE);
    addInferredStatement(RDFS.DOMAIN, RDFS.DOMAIN, RDF.PROPERTY);
    addInferredStatement(RDFS.RANGE, RDFS.DOMAIN, RDF.PROPERTY);
    addInferredStatement(RDFS.SUBPROPERTYOF, RDFS.DOMAIN, RDF.PROPERTY);
    addInferredStatement(RDFS.SUBCLASSOF, RDFS.DOMAIN, RDFS.CLASS);
    addInferredStatement(RDF.SUBJECT, RDFS.DOMAIN, RDF.STATEMENT);
    addInferredStatement(RDF.PREDICATE, RDFS.DOMAIN, RDF.STATEMENT);
    addInferredStatement(RDF.OBJECT, RDFS.DOMAIN, RDF.STATEMENT);
    addInferredStatement(RDFS.MEMBER, RDFS.DOMAIN, RDFS.RESOURCE);
    addInferredStatement(RDF.FIRST, RDFS.DOMAIN, RDF.LIST);
    addInferredStatement(RDF.REST, RDFS.DOMAIN, RDF.LIST);
    addInferredStatement(RDFS.SEEALSO, RDFS.DOMAIN, RDFS.RESOURCE);
    addInferredStatement(RDFS.ISDEFINEDBY, RDFS.DOMAIN, RDFS.RESOURCE);
    addInferredStatement(RDFS.COMMENT, RDFS.DOMAIN, RDFS.RESOURCE);
    addInferredStatement(RDFS.LABEL, RDFS.DOMAIN, RDFS.RESOURCE);
    addInferredStatement(RDF.VALUE, RDFS.DOMAIN, RDFS.RESOURCE);

    addInferredStatement(RDF.TYPE, RDFS.RANGE, RDFS.CLASS);
    addInferredStatement(RDFS.DOMAIN, RDFS.RANGE, RDFS.CLASS);
    addInferredStatement(RDFS.RANGE, RDFS.RANGE, RDFS.CLASS);
    addInferredStatement(RDFS.SUBPROPERTYOF, RDFS.RANGE, RDF.PROPERTY);
    addInferredStatement(RDFS.SUBCLASSOF, RDFS.RANGE, RDFS.CLASS);
    addInferredStatement(RDF.SUBJECT, RDFS.RANGE, RDFS.RESOURCE);
    addInferredStatement(RDF.PREDICATE, RDFS.RANGE, RDFS.RESOURCE);
    addInferredStatement(RDF.OBJECT, RDFS.RANGE, RDFS.RESOURCE);
    addInferredStatement(RDFS.MEMBER, RDFS.RANGE, RDFS.RESOURCE);
    addInferredStatement(RDF.FIRST, RDFS.RANGE, RDFS.RESOURCE);
    addInferredStatement(RDF.REST, RDFS.RANGE, RDF.LIST);
    addInferredStatement(RDFS.SEEALSO, RDFS.RANGE, RDFS.RESOURCE);
    addInferredStatement(RDFS.ISDEFINEDBY, RDFS.RANGE, RDFS.RESOURCE);
    addInferredStatement(RDFS.COMMENT, RDFS.RANGE, RDFS.LITERAL);
    addInferredStatement(RDFS.LABEL, RDFS.RANGE, RDFS.LITERAL);
    addInferredStatement(RDF.VALUE, RDFS.RANGE, RDFS.RESOURCE);

    addInferredStatement(RDF.ALT, RDFS.SUBCLASSOF, RDFS.CONTAINER);
    addInferredStatement(RDF.BAG, RDFS.SUBCLASSOF, RDFS.CONTAINER);
    addInferredStatement(RDF.SEQ, RDFS.SUBCLASSOF, RDFS.CONTAINER);
    addInferredStatement(RDFS.CONTAINERMEMBERSHIPPROPERTY, RDFS.SUBCLASSOF, RDF.PROPERTY);

    addInferredStatement(RDFS.ISDEFINEDBY, RDFS.SUBPROPERTYOF, RDFS.SEEALSO);

    addInferredStatement(RDF.XMLLITERAL, RDF.TYPE, RDFS.DATATYPE);
    addInferredStatement(RDF.XMLLITERAL, RDFS.SUBCLASSOF, RDFS.LITERAL);
    addInferredStatement(RDFS.DATATYPE, RDFS.SUBCLASSOF, RDFS.CLASS);
   
//    // NRL inverse
//    // FIXME made up a property for inverse-of rdf:type
//    addInferredStatement(RDF.TYPE, NRL_InverseProperty, new URIImpl(NRL_NS+"hasInstance"));
   

  }

  protected void doInferencing()
    throws SailException
  {
    if (!hasNewStatements()) {
      // There's nothing to do
      return;
    }

    // initialize some vars
    this.totalInferred = 0;
    int iteration = 0;
    int nofInferred = 1;

    // All rules need to be checked:
    for (int i = 0; i < RDFSPlusInversesRules.RULECOUNT; i++) {
      this.ruleCount[i] = 0;
      this.checkRuleNextIter[i] = true;
    }

    while (hasNewStatements()) {
      iteration++;
      this.logger.debug("starting iteration " + iteration);
      prepareIteration();

      nofInferred = 0;
      nofInferred += applyRule(RDFSPlusInversesRules.Rdf1);
      nofInferred += applyRule(RDFSPlusInversesRules.Rdfs2_1);
      nofInferred += applyRule(RDFSPlusInversesRules.Rdfs2_2);
      nofInferred += applyRule(RDFSPlusInversesRules.Rdfs3_1);
      nofInferred += applyRule(RDFSPlusInversesRules.Rdfs3_2);
      nofInferred += applyRule(RDFSPlusInversesRules.Rdfs4a);
      nofInferred += applyRule(RDFSPlusInversesRules.Rdfs4b);
      nofInferred += applyRule(RDFSPlusInversesRules.Rdfs5_1);
      nofInferred += applyRule(RDFSPlusInversesRules.Rdfs5_2);
      nofInferred += applyRule(RDFSPlusInversesRules.Rdfs6);
      nofInferred += applyRule(RDFSPlusInversesRules.Rdfs7_1);
      nofInferred += applyRule(RDFSPlusInversesRules.Rdfs7_2);
      nofInferred += applyRule(RDFSPlusInversesRules.Rdfs8);
      nofInferred += applyRule(RDFSPlusInversesRules.Rdfs9_1);
      nofInferred += applyRule(RDFSPlusInversesRules.Rdfs9_2);
      nofInferred += applyRule(RDFSPlusInversesRules.Rdfs10);
      nofInferred += applyRule(RDFSPlusInversesRules.Rdfs11_1);
      nofInferred += applyRule(RDFSPlusInversesRules.Rdfs11_2);
      nofInferred += applyRule(RDFSPlusInversesRules.Rdfs12);
      nofInferred += applyRule(RDFSPlusInversesRules.Rdfs13);
      nofInferred += applyRule(RDFSPlusInversesRules.RX1);
      nofInferred += applyRule(RDFSPlusInversesRules.N1a);
      nofInferred += applyRule(RDFSPlusInversesRules.N1b);
      nofInferred += applyRule(RDFSPlusInversesRules.N2a);
      nofInferred += applyRule(RDFSPlusInversesRules.N2b);
      nofInferred += applyRule(RDFSPlusInversesRules.N3);

      this.logger.debug("iteration " + iteration + " done; inferred " + nofInferred + " new statements");
      this.totalInferred += nofInferred;
    }

    // Print some statistics
    this.logger.debug("---RdfMTInferencer statistics:---");
    this.logger.debug("total statements inferred = " + this.totalInferred);
    for (int i = 0; i < RDFSPlusInversesRules.RULECOUNT; i++) {
      this.logger.debug("rule " + RDFSPlusInversesRules.RULENAMES[i] + ":\t#inferred=" + this.ruleCount[i]);
    }
    this.logger.debug("---end of statistics:---");
  }

  protected void prepareIteration() {
    for (int i = 0; i < RDFSPlusInversesRules.RULECOUNT; i++) {
      this.checkRule[i] = this.checkRuleNextIter[i];

      // reset for next iteration:
      this.checkRuleNextIter[i] = false;
    }

    this.newThisIteration = this.newStatements;
    this.newStatements = new GraphImpl();
  }

  protected boolean hasNewStatements() {
    return this.newStatements != null && !this.newStatements.isEmpty();
  }

  protected void updateTriggers(int ruleNo, int nofInferred) {
    if (nofInferred > 0) {
      this.ruleCount[ruleNo] += nofInferred;

      // Check which rules are triggered by this one.
      boolean[] triggers = RDFSPlusInversesRules.TRIGGERS[ruleNo];

      for (int i = 0; i < RDFSPlusInversesRules.RULECOUNT; i++) {
        if (triggers[i] == true) {
          this.checkRuleNextIter[i] = true;
        }
      }
    }
  }

  protected int applyRule(int rule)
    throws SailException
  {
    if (!this.checkRule[rule]) {
      return 0;
    }
    int nofInferred = 0;

    nofInferred = applyRuleInternal(rule);

    updateTriggers(rule, nofInferred);

    return nofInferred;
  }

  protected int applyRuleInternal(int rule)
    throws SailException
  {
    int result = 0;

    switch (rule) {
      case RDFSPlusInversesRules.Rdf1:
        result = applyRuleRdf1();
        break;
      case RDFSPlusInversesRules.Rdfs2_1:
        result = applyRuleRdfs2_1();
        break;
      case RDFSPlusInversesRules.Rdfs2_2:
        result = applyRuleRdfs2_2();
        break;
      case RDFSPlusInversesRules.Rdfs3_1:
        result = applyRuleRdfs3_1();
        break;
      case RDFSPlusInversesRules.Rdfs3_2:
        result = applyRuleRdfs3_2();
        break;
      case RDFSPlusInversesRules.Rdfs4a:
        result = applyRuleRdfs4a();
        break;
      case RDFSPlusInversesRules.Rdfs4b:
        result = applyRuleRdfs4b();
        break;
      case RDFSPlusInversesRules.Rdfs5_1:
        result = applyRuleRdfs5_1();
        break;
      case RDFSPlusInversesRules.Rdfs5_2:
        result = applyRuleRdfs5_2();
        break;
      case RDFSPlusInversesRules.Rdfs6:
        result = applyRuleRdfs6();
        break;
      case RDFSPlusInversesRules.Rdfs7_1:
        result = applyRuleRdfs7_1();
        break;
      case RDFSPlusInversesRules.Rdfs7_2:
        result = applyRuleRdfs7_2();
        break;
      case RDFSPlusInversesRules.Rdfs8:
        result = applyRuleRdfs8();
        break;
      case RDFSPlusInversesRules.Rdfs9_1:
        result = applyRuleRdfs9_1();
        break;
      case RDFSPlusInversesRules.Rdfs9_2:
        result = applyRuleRdfs9_2();
        break;
      case RDFSPlusInversesRules.Rdfs10:
        result = applyRuleRdfs10();
        break;
      case RDFSPlusInversesRules.Rdfs11_1:
        result = applyRuleRdfs11_1();
        break;
      case RDFSPlusInversesRules.Rdfs11_2:
        result = applyRuleRdfs11_2();
        break;
      case RDFSPlusInversesRules.Rdfs12:
        result = applyRuleRdfs12();
        break;
      case RDFSPlusInversesRules.Rdfs13:
        result = applyRuleRdfs13();
        break;
      case RDFSPlusInversesRules.RX1:
        result = applyRuleX1();
        break;
      case RDFSPlusInversesRules.N1a:
        result = applyRuleN1a();
        break;
      case RDFSPlusInversesRules.N1b:
        result = applyRuleN1b();
        break;
      case RDFSPlusInversesRules.N2a:
        result = applyRuleN2a();
        break;
      case RDFSPlusInversesRules.N2b:
        result = applyRuleN2b();
        break;
      case RDFSPlusInversesRules.N3:
        result = applyRuleN3();
        break;
      default:
        throw new AssertionError("Should be unreachable code");
    }
    // ThreadLog.trace("Rule " + RDFSRules.RULENAMES[rule] + " inferred " +
    // result + " new triples.");
    return result;
  }

  /*
   * rdf1. xxx aaa yyy --> aaa rdf:type rdf:Property
   */
  private int applyRuleRdf1()
    throws SailException
  {
    int nofInferred = 0;

    Iterator<Statement> iter = this.newThisIteration.match(null, null, null);

    while (iter.hasNext()) {
      Statement st = iter.next();

      boolean added = addInferredStatement(st.getPredicate(), RDF.TYPE, RDF.PROPERTY);

      if (added) {
        nofInferred++;
      }
    }

    return nofInferred;
  }

  /*
   * rdfs2. 2_1. xxx aaa yyy && (nt) aaa rdfs:domain zzz --> (t1) xxx rdf:type
   * zzz (t2)
   */
  private int applyRuleRdfs2_1()
    throws SailException
  {
    int nofInferred = 0;

    Iterator<Statement> ntIter = this.newThisIteration.match(null, null, null);

    while (ntIter.hasNext()) {
      Statement nt = ntIter.next();

      Resource xxx = nt.getSubject();
      URI aaa = nt.getPredicate();

      CloseableIteration<? extends Statement, SailException> t1Iter;
      t1Iter = getWrappedConnection().getStatements(aaa, RDFS.DOMAIN, null, true);

      while (t1Iter.hasNext()) {
        Statement t1 = t1Iter.next();

        Value zzz = t1.getObject();
        if (zzz instanceof Resource) {
          boolean added = addInferredStatement(xxx, RDF.TYPE, zzz);
          if (added) {
            nofInferred++;
          }
        }
      }
      t1Iter.close();
    }

    return nofInferred;
  }

  /*
   * rdfs2. 2_2. aaa rdfs:domain zzz && (nt) xxx aaa yyy --> (t1) xxx rdf:type
   * zzz (t2)
   */
  private int applyRuleRdfs2_2()
    throws SailException
  {
    int nofInferred = 0;

    Iterator<Statement> ntIter = this.newThisIteration.match(null, RDFS.DOMAIN, null);

    while (ntIter.hasNext()) {
      Statement nt = ntIter.next();

      Resource aaa = nt.getSubject();
      Value zzz = nt.getObject();

      if (aaa instanceof URI && zzz instanceof Resource) {
        CloseableIteration<? extends Statement, SailException> t1Iter;
        t1Iter = getWrappedConnection().getStatements(null, (URI)aaa, null, true);

        while (t1Iter.hasNext()) {
          Statement t1 = t1Iter.next();

          Resource xxx = t1.getSubject();
          boolean added = addInferredStatement(xxx, RDF.TYPE, zzz);
          if (added) {
            nofInferred++;
          }
        }
        t1Iter.close();
      }
    }

    return nofInferred;
  }

  /*
   * rdfs3. 3_1. xxx aaa uuu && (nt) aaa rdfs:range zzz --> (t1) uuu rdf:type
   * zzz (t2)
   */
  private int applyRuleRdfs3_1()
    throws SailException
  {
    int nofInferred = 0;

    Iterator<Statement> ntIter = this.newThisIteration.match(null, null, null);

    while (ntIter.hasNext()) {
      Statement nt = ntIter.next();

      URI aaa = nt.getPredicate();
      Value uuu = nt.getObject();

      if (uuu instanceof Resource) {
        CloseableIteration<? extends Statement, SailException> t1Iter;
        t1Iter = getWrappedConnection().getStatements(aaa, RDFS.RANGE, null, true);

        while (t1Iter.hasNext()) {
          Statement t1 = t1Iter.next();

          Value zzz = t1.getObject();
          if (zzz instanceof Resource) {
            boolean added = addInferredStatement((Resource)uuu, RDF.TYPE, zzz);
            if (added) {
              nofInferred++;
            }
          }
        }
        t1Iter.close();
      }
    }
    return nofInferred;
  }

  /*
   * rdfs3. 3_2. aaa rdfs:range zzz && (nt) xxx aaa uuu --> (t1) uuu rdf:type
   * zzz (t2)
   */
  private int applyRuleRdfs3_2()
    throws SailException
  {
    int nofInferred = 0;

    Iterator<Statement> ntIter = this.newThisIteration.match(null, RDFS.RANGE, null);

    while (ntIter.hasNext()) {
      Statement nt = ntIter.next();

      Resource aaa = nt.getSubject();
      Value zzz = nt.getObject();

      if (aaa instanceof URI && zzz instanceof Resource) {
        CloseableIteration<? extends Statement, SailException> t1Iter;
        t1Iter = getWrappedConnection().getStatements(null, (URI)aaa, null, true);

        while (t1Iter.hasNext()) {
          Statement t1 = t1Iter.next();

          Value uuu = t1.getObject();
          if (uuu instanceof Resource) {
            boolean added = addInferredStatement((Resource)uuu, RDF.TYPE, zzz);
            if (added) {
              nofInferred++;
            }
          }
        }
        t1Iter.close();
      }
    }

    return nofInferred;

  }

  /*
   * rdfs4a. xxx aaa yyy --> xxx rdf:type rdfs:Resource
   */
  private int applyRuleRdfs4a()
    throws SailException
  {
    int nofInferred = 0;

    Iterator<Statement> iter = this.newThisIteration.match(null, null, null);

    while (iter.hasNext()) {
      Statement st = iter.next();

      boolean added = addInferredStatement(st.getSubject(), RDF.TYPE, RDFS.RESOURCE);
      if (added) {
        nofInferred++;
      }
    }

    return nofInferred;
  }

  /*
   * rdfs4b. xxx aaa uuu --> uuu rdf:type rdfs:Resource
   */
  private int applyRuleRdfs4b()
    throws SailException
  {
    int nofInferred = 0;

    Iterator<Statement> iter = this.newThisIteration.match(null, null, null);

    while (iter.hasNext()) {
      Statement st = iter.next();

      Value uuu = st.getObject();
      if (uuu instanceof Resource) {
        boolean added = addInferredStatement((Resource)uuu, RDF.TYPE, RDFS.RESOURCE);
        if (added) {
          nofInferred++;
        }
      }
    }

    return nofInferred;
  }

  /*
   * rdfs5. 5_1. aaa rdfs:subPropertyOf bbb && (nt) bbb rdfs:subPropertyOf ccc
   * --> (t1) aaa rdfs:subPropertyOf ccc (t2)
   */
  private int applyRuleRdfs5_1()
    throws SailException
  {
    int nofInferred = 0;

    Iterator<Statement> ntIter = this.newThisIteration.match(null, RDFS.SUBPROPERTYOF, null);

    while (ntIter.hasNext()) {
      Statement nt = ntIter.next();

      Resource aaa = nt.getSubject();
      Value bbb = nt.getObject();

      if (bbb instanceof Resource) {
        CloseableIteration<? extends Statement, SailException> t1Iter;
        t1Iter = getWrappedConnection().getStatements((Resource)bbb, RDFS.SUBPROPERTYOF, null, true);

        while (t1Iter.hasNext()) {
          Statement t1 = t1Iter.next();

          Value ccc = t1.getObject();
          if (ccc instanceof Resource) {
            boolean added = addInferredStatement(aaa, RDFS.SUBPROPERTYOF, ccc);
            if (added) {
              nofInferred++;
            }
          }
        }
        t1Iter.close();

      }
    }

    return nofInferred;
  }

  /*
   * rdfs5. 5_2. bbb rdfs:subPropertyOf ccc && (nt) aaa rdfs:subPropertyOf bbb
   * --> (t1) aaa rdfs:subPropertyOf ccc (t2)
   */
  private int applyRuleRdfs5_2()
    throws SailException
  {
    int nofInferred = 0;

    Iterator<Statement> ntIter = this.newThisIteration.match(null, RDFS.SUBPROPERTYOF, null);

    while (ntIter.hasNext()) {
      Statement nt = ntIter.next();

      Resource bbb = nt.getSubject();
      Value ccc = nt.getObject();

      if (ccc instanceof Resource) {
        CloseableIteration<? extends Statement, SailException> t1Iter;
        t1Iter = getWrappedConnection().getStatements(null, RDFS.SUBPROPERTYOF, bbb, true);

        while (t1Iter.hasNext()) {
          Statement t1 = t1Iter.next();

          Resource aaa = t1.getSubject();
          boolean added = addInferredStatement(aaa, RDFS.SUBPROPERTYOF, ccc);
          if (added) {
            nofInferred++;
          }
        }
        t1Iter.close();
      }
    }

    return nofInferred;
  }

  /*
   * rdfs6. xxx rdf:type rdf:Property --> xxx rdfs:subPropertyOf xxx
   * reflexivity of rdfs:subPropertyOf
   */
  private int applyRuleRdfs6()
    throws SailException
  {
    int nofInferred = 0;

    Iterator<Statement> iter = this.newThisIteration.match(null, RDF.TYPE, RDF.PROPERTY);

    while (iter.hasNext()) {
      Statement st = iter.next();

      Resource xxx = st.getSubject();
      boolean added = addInferredStatement(xxx, RDFS.SUBPROPERTYOF, xxx);
      if (added) {
        nofInferred++;
      }
    }

    return nofInferred;
  }

  /*
   * rdfs7. 7_1. xxx aaa yyy && (nt) aaa rdfs:subPropertyOf bbb --> (t1) xxx
   * bbb yyy (t2)
   */
  private int applyRuleRdfs7_1()
    throws SailException
  {
    int nofInferred = 0;

    Iterator<Statement> ntIter = this.newThisIteration.match(null, null, null);

    while (ntIter.hasNext()) {
      Statement nt = ntIter.next();

      Resource xxx = nt.getSubject();
      URI aaa = nt.getPredicate();
      Value yyy = nt.getObject();

      CloseableIteration<? extends Statement, SailException> t1Iter;
      t1Iter = getWrappedConnection().getStatements(aaa, RDFS.SUBPROPERTYOF, null, true);

      while (t1Iter.hasNext()) {
        Statement t1 = t1Iter.next();

        Value bbb = t1.getObject();
        if (bbb instanceof URI) {
          boolean added = addInferredStatement(xxx, (URI)bbb, yyy);
          if (added) {
            nofInferred++;
          }
        }
      }
      t1Iter.close();
    }

    return nofInferred;
  }

  /*
   * rdfs7. 7_2. aaa rdfs:subPropertyOf bbb && (nt) xxx aaa yyy --> (t1) xxx
   * bbb yyy (t2)
   */
  private int applyRuleRdfs7_2()
    throws SailException
  {
    int nofInferred = 0;

    Iterator<Statement> ntIter = this.newThisIteration.match(null, RDFS.SUBPROPERTYOF, null);

    while (ntIter.hasNext()) {
      Statement nt = ntIter.next();

      Resource aaa = nt.getSubject();
      Value bbb = nt.getObject();

      if (aaa instanceof URI && bbb instanceof URI) {
        CloseableIteration<? extends Statement, SailException> t1Iter;
        t1Iter = getWrappedConnection().getStatements(null, (URI)aaa, null, true);

        while (t1Iter.hasNext()) {
          Statement t1 = t1Iter.next();

          Resource xxx = t1.getSubject();
          Value yyy = t1.getObject();

          boolean added = addInferredStatement(xxx, (URI)bbb, yyy);
          if (added) {
            nofInferred++;
          }
        }
        t1Iter.close();
      }
    }

    return nofInferred;
  }

  /*
   * rdfs8. xxx rdf:type rdfs:Class --> xxx rdfs:subClassOf rdfs:Resource
   */
  private int applyRuleRdfs8()
    throws SailException
  {
    int nofInferred = 0;

    Iterator<Statement> iter = this.newThisIteration.match(null, RDF.TYPE, RDFS.CLASS);

    while (iter.hasNext()) {
      Statement st = iter.next();

      Resource xxx = st.getSubject();

      boolean added = addInferredStatement(xxx, RDFS.SUBCLASSOF, RDFS.RESOURCE);
      if (added) {
        nofInferred++;
      }
    }

    return nofInferred;
  }

  /*
   * rdfs9. 9_1. xxx rdfs:subClassOf yyy && (nt) aaa rdf:type xxx --> (t1) aaa
   * rdf:type yyy (t2)
   */
  private int applyRuleRdfs9_1()
    throws SailException
  {
    int nofInferred = 0;

    Iterator<Statement> ntIter = this.newThisIteration.match(null, RDFS.SUBCLASSOF, null);

    while (ntIter.hasNext()) {
      Statement nt = ntIter.next();

      Resource xxx = nt.getSubject();
      Value yyy = nt.getObject();

      if (yyy instanceof Resource) {
        CloseableIteration<? extends Statement, SailException> t1Iter;
        t1Iter = getWrappedConnection().getStatements(null, RDF.TYPE, xxx, true);

        while (t1Iter.hasNext()) {
          Statement t1 = t1Iter.next();

          Resource aaa = t1.getSubject();

          boolean added = addInferredStatement(aaa, RDF.TYPE, yyy);
          if (added) {
            nofInferred++;
          }
        }
        t1Iter.close();
      }
    }

    return nofInferred;
  }

  /*
   * rdfs9. 9_2. aaa rdf:type xxx && (nt) xxx rdfs:subClassOf yyy --> (t1) aaa
   * rdf:type yyy (t2)
   */
  private int applyRuleRdfs9_2()
    throws SailException
  {
    int nofInferred = 0;

    Iterator<Statement> ntIter = this.newThisIteration.match(null, RDF.TYPE, null);

    while (ntIter.hasNext()) {
      Statement nt = ntIter.next();

      Resource aaa = nt.getSubject();
      Value xxx = nt.getObject();

      if (xxx instanceof Resource) {
        CloseableIteration<? extends Statement, SailException> t1Iter;
        t1Iter = getWrappedConnection().getStatements((Resource)xxx, RDFS.SUBCLASSOF, null, true);

        while (t1Iter.hasNext()) {
          Statement t1 = t1Iter.next();

          Value yyy = t1.getObject();

          if (yyy instanceof Resource) {
            boolean added = addInferredStatement(aaa, RDF.TYPE, yyy);
            if (added) {
              nofInferred++;
            }
          }
        }
        t1Iter.close();
      }
    }

    return nofInferred;
  }

  /*
   * rdfs10. xxx rdf:type rdfs:Class --> xxx rdfs:subClassOf xxx reflexivity of
   * rdfs:subClassOf
   */
  private int applyRuleRdfs10()
    throws SailException
  {
    int nofInferred = 0;

    Iterator<Statement> iter = this.newThisIteration.match(null, RDF.TYPE, RDFS.CLASS);

    while (iter.hasNext()) {
      Statement st = iter.next();

      Resource xxx = st.getSubject();

      boolean added = addInferredStatement(xxx, RDFS.SUBCLASSOF, xxx);
      if (added) {
        nofInferred++;
      }
    }

    return nofInferred;
  }

  /*
   * rdfs11. 11_1. xxx rdfs:subClassOf yyy && (nt) yyy rdfs:subClassOf zzz -->
   * (t1) xxx rdfs:subClassOf zzz (t2)
   */
  private int applyRuleRdfs11_1()
    throws SailException
  {
    int nofInferred = 0;

    Iterator<Statement> ntIter = this.newThisIteration.match(null, RDFS.SUBCLASSOF, null);

    while (ntIter.hasNext()) {
      Statement nt = ntIter.next();

      Resource xxx = nt.getSubject();
      Value yyy = nt.getObject();

      if (yyy instanceof Resource) {
        CloseableIteration<? extends Statement, SailException> t1Iter;
        t1Iter = getWrappedConnection().getStatements((Resource)yyy, RDFS.SUBCLASSOF, null, true);

        while (t1Iter.hasNext()) {
          Statement t1 = t1Iter.next();

          Value zzz = t1.getObject();

          if (zzz instanceof Resource) {
            boolean added = addInferredStatement(xxx, RDFS.SUBCLASSOF, zzz);
            if (added) {
              nofInferred++;
            }
          }
        }
        t1Iter.close();
      }
    }

    return nofInferred;
  }

  /*
   * rdfs11. 11_2. yyy rdfs:subClassOf zzz && (nt) xxx rdfs:subClassOf yyy -->
   * (t1) xxx rdfs:subClassOf zzz (t2)
   */
  private int applyRuleRdfs11_2()
    throws SailException
  {
    int nofInferred = 0;

    Iterator<Statement> ntIter = this.newThisIteration.match(null, RDFS.SUBCLASSOF, null);

    while (ntIter.hasNext()) {
      Statement nt = ntIter.next();

      Resource yyy = nt.getSubject();
      Value zzz = nt.getObject();

      if (zzz instanceof Resource) {
        CloseableIteration<? extends Statement, SailException> t1Iter;
        t1Iter = getWrappedConnection().getStatements(null, RDFS.SUBCLASSOF, yyy, true);

        while (t1Iter.hasNext()) {
          Statement t1 = t1Iter.next();

          Resource xxx = t1.getSubject();

          boolean added = addInferredStatement(xxx, RDFS.SUBCLASSOF, zzz);
          if (added) {
            nofInferred++;
          }
        }
        t1Iter.close();
      }
    }

    return nofInferred;
  }

  /*
   * rdfs12. xxx rdf:type rdfs:ContainerMembershipProperty --> xxx
   * rdfs:subPropertyOf rdfs:member
   */
  private int applyRuleRdfs12()
    throws SailException
  {
    int nofInferred = 0;

    Iterator<Statement> iter = this.newThisIteration.match(null, RDF.TYPE, RDFS.CONTAINERMEMBERSHIPPROPERTY);

    while (iter.hasNext()) {
      Statement st = iter.next();

      Resource xxx = st.getSubject();

      boolean added = addInferredStatement(xxx, RDFS.SUBPROPERTYOF, RDFS.MEMBER);
      if (added) {
        nofInferred++;
      }
    }

    return nofInferred;
  }

  /*
   * rdfs13. xxx rdf:type rdfs:Datatype --> xxx rdfs:subClassOf rdfs:Literal
   */
  private int applyRuleRdfs13()
    throws SailException
  {
    int nofInferred = 0;

    Iterator<Statement> iter = this.newThisIteration.match(null, RDF.TYPE, RDFS.DATATYPE);

    while (iter.hasNext()) {
      Statement st = iter.next();

      Resource xxx = st.getSubject();

      boolean added = addInferredStatement(xxx, RDFS.SUBCLASSOF, RDFS.LITERAL);
      if (added) {
        nofInferred++;
      }
    }

    return nofInferred;
  }

  /*
   * X1. xxx rdf:_* yyy --> rdf:_* rdf:type rdfs:ContainerMembershipProperty
   * This is an extra rule for list membership properties (_1, _2, _3, ...).
   * The RDF MT does not specificy a production for this.
   */
  private int applyRuleX1()
    throws SailException
  {
    int nofInferred = 0;

    String prefix = RDF.NAMESPACE + "_";
    Iterator<Statement> iter = this.newThisIteration.match(null, null, null);

    while (iter.hasNext()) {
      Statement st = iter.next();

      URI predNode = st.getPredicate();
      String predURI = predNode.toString();

      if (predURI.startsWith(prefix) && isValidPredicateNumber(predURI.substring(prefix.length()))) {
        boolean added = addInferredStatement(predNode, RDF.TYPE, RDFS.CONTAINERMEMBERSHIPPROPERTY);
        if (added) {
          nofInferred++;
        }
      }
    }

    return nofInferred;
  }

  /**
   * xxx nrl:inverseProperty yyy
   * aaa xxx bbb
   * -->
   * bbb yyy aaa
   * @return
   * @throws SailException
   */
  private int applyRuleN1a()
  throws SailException
{
  int nofInferred = 0;
 
  Iterator<Statement> ntIter = this.newThisIteration.match(null, NRL_InverseProperty, null);

  while (ntIter.hasNext()) {
    Statement nt = ntIter.next();

    Resource xxx = nt.getSubject();
    Value yyy = nt.getObject();

    if (xxx instanceof URI && yyy instanceof URI) {
      // apply to triples using the property
      CloseableIteration<? extends Statement, SailException> t1Iter;
      t1Iter = getWrappedConnection().getStatements(null, (URI)xxx, null, true);

      while (t1Iter.hasNext()) {
        Statement t1 = t1Iter.next();

        Value aaa = t1.getSubject();
        Value bbb = t1.getObject();
        if (bbb instanceof Resource) {
          boolean added = addInferredStatement((Resource)bbb, (URI) yyy, aaa);
          if (added) {
            nofInferred++;
          }
        }
      }
      t1Iter.close();
    }
  }

  return nofInferred;
}

  /**
   * aaa xxx bbb
   * xxx nrl:inverseProperty yyy
   * -->
   * bbb yyy aaa
   * @return
   * @throws SailException
   */
  private int applyRuleN1b()
  throws SailException
{
  int nofInferred = 0;
 
  Iterator<Statement> ntIter = this.newThisIteration.match(null, null, null);

  while (ntIter.hasNext()) {
    Statement nt = ntIter.next();

    Resource xxx = nt.getPredicate();

    CloseableIteration<? extends Statement, SailException> t1Iter;
    t1Iter = getWrappedConnection().getStatements(xxx,NRL_InverseProperty, null, true);

    while (t1Iter.hasNext()) {
      Statement t1 = t1Iter.next();

      Value yyy = t1.getObject();
      if (yyy instanceof URI) {
        Resource aaa =   nt.getSubject();
        Value bbb = nt.getObject();
        boolean added = addInferredStatement((Resource)bbb, (URI) yyy, aaa);
        if (added) {
          nofInferred++;
        }
      }
    }
    t1Iter.close();
  }

  return nofInferred;
}

  /**
   * New: ppp nrl:inverseProperty qqq
   *
   * ... AND (case 1)
   * rrr rdfs:subPropertyOf  ppp /\ rrr nrl:inverseProperty sss
   * -->
   * sss rdfs:subPropertyOf  qqq
   *
   *
   * ... AND (case 2)
   * ppp rdfs:subPropertyOf  ttt (2)
   * ttt nrl:inverseProperty uuu (1)
   * -->
   * qqq rdfs:subPropertyOf  uuu
   *
   * @return
   * @throws SailException
   */
  private int applyRuleN2a()
  throws SailException
  {
    int nofInferred = 0;
    Iterator<Statement> it1 = this.newThisIteration.match(null, NRL_InverseProperty, null);
    while (it1.hasNext()) {
      Statement stmt1 = it1.next();
      Resource ppp = stmt1.getSubject();
      Value qqq = stmt1.getObject();
      if(qqq instanceof Resource) {
        // case 1
        CloseableIteration<? extends Statement, SailException> it2;
        it2 = getWrappedConnection().getStatements(null,RDFS.SUBPROPERTYOF, ppp, true);
        while (it2.hasNext()) {
          Statement stmt2 = it2.next();
          Resource rrr = stmt2.getSubject();
          CloseableIteration<? extends Statement, SailException> it3;
          it3 = getWrappedConnection().getStatements(rrr,NRL_InverseProperty, null, true);
          while (it3.hasNext()) {
            Statement stmt3 = it3.next();
            Value sss = stmt3.getObject();
            if( sss instanceof Resource) {
              boolean added = addInferredStatement((Resource)sss, RDFS.SUBPROPERTYOF, qqq);
              if (added) {
                nofInferred++;
              }
            }
          }
          it3.close();
        }
        it2.close();
        // case 2
        it2 = getWrappedConnection().getStatements(ppp,RDFS.SUBPROPERTYOF, null, true);
        while (it2.hasNext()) {
          Statement stmt2 = it2.next();
          Value ttt = stmt2.getObject();
          if( ttt instanceof Resource) {
            CloseableIteration<? extends Statement, SailException> it3;
            it3 = getWrappedConnection().getStatements( (Resource) ttt,NRL_InverseProperty, null, true);
            while (it3.hasNext()) {
              Statement stmt3 = it3.next();
              Value uuu = stmt3.getObject();
              if( uuu instanceof Resource) {
                boolean added = addInferredStatement((Resource)qqq, RDFS.SUBPROPERTYOF, uuu);
                if (added) {
                  nofInferred++;
                }
              }
            }
            it3.close();
          }
        }
        it2.close();
      }
     
    }
    return nofInferred;
 
 
  /**
   * rrr rdfs:subPropertyOf  ppp
   * rrr nrl:inverseProperty sss
   * ppp nrl:inverseProperty qqq
   * -->
   * sss rdfs:subPropertyOf  qqq
   * @return
   * @throws SailException
   */
  private int applyRuleN2b()
  throws SailException
  {
    int nofInferred = 0;
    Iterator<Statement> it1 = this.newThisIteration.match(null, RDFS.SUBPROPERTYOF, null);
    while (it1.hasNext()) {
      Statement stmt1 = it1.next();
      Resource rrr = stmt1.getSubject();
      Value ppp = stmt1.getObject();
      if(ppp instanceof Resource) {
        CloseableIteration<? extends Statement, SailException> it2;
        it2 = getWrappedConnection().getStatements(rrr,NRL_InverseProperty, null, true);
        while (it2.hasNext()) {
          Statement stmt2 = it2.next();
          Value sss = stmt2.getObject();
          if(sss instanceof Resource) {
            CloseableIteration<? extends Statement, SailException> it3;
            it3 = getWrappedConnection().getStatements( (Resource) ppp,NRL_InverseProperty, null, true);
            while (it3.hasNext()) {
              Statement stmt3 = it3.next();
              Value qqq = stmt3.getObject();
              if( qqq instanceof Resource) {
                boolean added = addInferredStatement((Resource)sss, RDFS.SUBPROPERTYOF, qqq);
                if (added) {
                  nofInferred++;
                }
              }
            }
            it3.close();
          }
        }
        it2.close();
      }
    }
    return nofInferred;
 
 
  /**
   * ppp nrl:inverseProperty qqq
   * -->
   * qqq nrl:inverseProperty ppp
   * ppp a rdf:Property
   * qqq a rdf:Property
   *
   * @return
   * @throws SailException
   */
  private int applyRuleN3()
  throws SailException
  {
    int nofInferred = 0;
   
    Iterator<Statement> it1 = this.newThisIteration.match(null, NRL_InverseProperty, null);
    while (it1.hasNext()) {
      Statement stmt1 = it1.next();
      Resource ppp = stmt1.getSubject();
      if(ppp instanceof URI) {
        // infer: ppp is a property
        boolean addedPPP = addInferredStatement(ppp, RDF.TYPE, RDF.PROPERTY);
        if (addedPPP) {
          nofInferred++;
        }
      }
      Value qqq = stmt1.getObject();
      if(qqq instanceof Resource) {
        if(qqq instanceof URI) {
          // infer: qqq is a property
          boolean addedQQQ = addInferredStatement((URI)qqq, RDF.TYPE, RDF.PROPERTY);
          if (addedQQQ) {
            nofInferred++;
          }
        }
        if(! qqq.equals(ppp)) {
          // infer: qqq inverse ppp
          boolean added = addInferredStatement((Resource)qqq, NRL_InverseProperty, ppp);
          if (added) {
            nofInferred++;
          }
        }
      }
    }
    return nofInferred;
 

  /**
   * Util method for {@link #applyRuleX1}.
   */
  private boolean isValidPredicateNumber(String str) {
    int strLength = str.length();

    if (strLength == 0) {
      return false;
    }

    for (int i = 0; i < strLength; i++) {
      if (!ASCIIUtil.isNumber(str.charAt(i))) {
        return false;
      }
    }

    // No leading zeros
    if (str.charAt(0) == '0') {
      return false;
    }

    return true;
  }
}
TOP

Related Classes of org.semweb4j.sesame.ForwardChainingRDFSPlusInverseInferencerConnection

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.