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

org.openrdf.sesame.sailimpl.rdbms.RdfMTDependencyInferencer Maven / Gradle / Ivy

Go to download

Sesame is an open source Java framework for storing, querying and reasoning with RDF.

The newest version!
/*  Sesame - Storage and Querying architecture for RDF and RDF Schema
 *  Copyright (C) 2001-2006 Aduna
 *
 *  Contact: 
 *  	Aduna
 *  	Prinses Julianaplein 14 b
 *  	3817 CS Amersfoort
 *  	The Netherlands
 *  	tel. +33 (0)33 465 99 87
 *  	fax. +33 (0)33 465 99 87
 *
 *  	http://aduna-software.com/
 *  	http://www.openrdf.org/
 *  
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.openrdf.sesame.sailimpl.rdbms;

import java.sql.SQLException;

import org.openrdf.util.log.ThreadLog;
import org.openrdf.vocabulary.RDF;

/**
 * Dependency inferencer that infers the depencies between statements based on
 * the rules from the RDF Model Theory Recommendation (10 February 2004).
 * See http://www.w3.org/TR/2004/REC-rdf-mt-20040210/. The dependencies are
 * stored in the DEPEND_TABLE. This inferencer operates directly on the database
 * used by the RdfSchemaRepository.
 **/
public class RdfMTDependencyInferencer implements TableNames {

/*----------------------------------------+
| Variables                               |
+----------------------------------------*/

	protected RdfSchemaRepository _sail;
	protected RDBMS _rdbms;

/*----------------------------------------+
| Constructors                            |
+----------------------------------------*/

	public RdfMTDependencyInferencer(RdfSchemaRepository sail, RDBMS rdbms) {
		_sail = sail;
		_rdbms = rdbms;
	}

/*----------------------------------------+
| Methods                                 |
+----------------------------------------*/

	/**
	 * Marks all statements that are in ALL_NEW_TRIPLES_TABLE as axioms.
	 **/
	public void markAxioms()
		throws SQLException
	{
		ThreadLog.trace("adding dependencies for axioms");
		_rdbms.executeUpdate(
				"INSERT INTO " + DEPEND_TABLE +
				" SELECT id, 0, 0 FROM " + ALL_NEW_TRIPLES_TABLE);
		ThreadLog.trace("dependencies for axioms added");
	}

	/**
	 * Processes the new statements that are in ALL_NEW_TRIPLES_TABLE and
	 * records there dependencies in the DEPEND_TABLE.
	 **/
	public void processNewStatements()
		throws SQLException
	{
		ThreadLog.trace("adding dependencies for new statements");
		_addRuleRdf1Dependencies();
		_addRuleRdfs2Dependencies();
		_addRuleRdfs3Dependencies();
		_addRuleRdfs4aDependencies();
		_addRuleRdfs4bDependencies();
		_addRuleRdfs5Dependencies();
		_addRuleRdfs6Dependencies();
		_addRuleRdfs7Dependencies();
		_addRuleRdfs8Dependencies();
		_addRuleRdfs9Dependencies();
		_addRuleRdfs10Dependencies();
		_addRuleRdfs11Dependencies();
		_addRuleRdfs12Dependencies();
		_addRuleRdfs13Dependencies();
		_addRuleX1Dependencies();
		ThreadLog.trace("dependencies for new statements added");
	}
		
	/* 1. xxx aaa yyy --> aaa rdf:type rdf:Property */
	protected void _addRuleRdf1Dependencies()
		throws SQLException
	{
		_rdbms.executeUpdate(
				"INSERT INTO " + DEPEND_TABLE + 
				" SELECT t.id, dep1.id, 0 FROM " +
				ALL_NEW_TRIPLES_TABLE + " dep1, " +
				TRIPLES_TABLE + " t " +
				"WHERE dep1.pred = t.subj" +
				" AND t.pred = " + _sail.rdfTypeId +
				" AND t.obj = " + _sail.rdfPropertyId +
				" AND dep1.id <> t.id");
	}

	/* 2. xxx aaa yyy && aaa rdfs:domain zzz --> xxx rdf:type zzz */
	protected void _addRuleRdfs2Dependencies()
		throws SQLException
	{
		// xxx aaa yyy in ALL_NEW_TRIPLES_TABLE:
		_rdbms.executeUpdate(
				"INSERT INTO " + DEPEND_TABLE + 
				" SELECT t.id, dep1.id, dep2.id FROM " +
				ALL_NEW_TRIPLES_TABLE + " dep1, " +
				TRIPLES_TABLE + " dep2, " +
				TRIPLES_TABLE + " t " +
				"WHERE dep1.pred = dep2.subj" +
				" AND dep1.subj = t.subj" +
				" AND dep2.pred = " + _sail.rdfsDomainId +
				" AND dep2.obj = t.obj" + 
				" AND t.pred = " + _sail.rdfTypeId +
				" AND dep1.id <> t.id");

		// aaa rdfs:domain zzz in ALL_NEW_TRIPLES_TABLE:
		_rdbms.executeUpdate(
				"INSERT INTO " + DEPEND_TABLE + 
				" SELECT t.id, dep1.id, dep2.id FROM " +
				TRIPLES_TABLE + " dep1, " +
				ALL_NEW_TRIPLES_TABLE + " dep2, " +
				TRIPLES_TABLE + " t " +
				"WHERE dep1.pred = dep2.subj" +
				" AND dep1.subj = t.subj" +
				" AND dep2.pred = " + _sail.rdfsDomainId +
				" AND dep2.obj = t.obj" + 
				" AND t.pred = " + _sail.rdfTypeId +
				" AND dep1.id <> t.id");
	}

	/* xxx aaa uuu && aaa rdfs:range zzz --> uuu rdf:type zzz */
	protected void _addRuleRdfs3Dependencies()
		throws SQLException
	{
		// xxx aaa uuu in ALL_NEW_TRIPLES_TABLE:
		_rdbms.executeUpdate(
				"INSERT INTO " + DEPEND_TABLE + 
				" SELECT t.id, dep1.id, dep2.id FROM " +
				ALL_NEW_TRIPLES_TABLE + " dep1, " +
				TRIPLES_TABLE + " dep2, " +
				TRIPLES_TABLE + " t " +
				"WHERE dep1.pred = dep2.subj" +
				" AND dep1.obj = t.subj" +
				" AND dep2.pred = " + _sail.rdfsRangeId +
				" AND dep2.obj = t.obj" + 
				" AND t.pred = " + _sail.rdfTypeId +
				" AND dep1.id <> t.id");

		// aaa rdfs:range zzz in ALL_NEW_TRIPLES_TABLE:
		_rdbms.executeUpdate(
				"INSERT INTO " + DEPEND_TABLE + 
				" SELECT t.id, dep1.id, dep2.id FROM " +
				TRIPLES_TABLE + " dep1, " +
				ALL_NEW_TRIPLES_TABLE + " dep2, " +
				TRIPLES_TABLE + " t " +
				"WHERE dep1.pred = dep2.subj" +
				" AND dep1.obj = t.subj" +
				" AND dep2.pred = " + _sail.rdfsRangeId +
				" AND dep2.obj = t.obj" + 
				" AND t.pred = " + _sail.rdfTypeId +
				" AND dep1.id <> t.id");
	}

	/* xxx aaa yyy --> xxx rdf:type rdfs:Resource */
	protected void _addRuleRdfs4aDependencies()
		throws SQLException
	{
		_rdbms.executeUpdate(
				"INSERT INTO " + DEPEND_TABLE + 
				" SELECT t.id, dep1.id, 0 FROM " +
				ALL_NEW_TRIPLES_TABLE + " dep1, " +
				TRIPLES_TABLE + " t " +
				"WHERE dep1.subj = t.subj" +
				" AND t.pred = " + _sail.rdfTypeId +
				" AND t.obj = " + _sail.rdfsResourceId +
				" AND dep1.id <> t.id");
	}

	/* xxx aaa uuu --> uuu rdf:type rdfs:Resource */
	protected void _addRuleRdfs4bDependencies()
		throws SQLException
	{
		_rdbms.executeUpdate(
				"INSERT INTO " + DEPEND_TABLE + 
				" SELECT t.id, dep1.id, 0 FROM " +
				ALL_NEW_TRIPLES_TABLE + " dep1, " +
				TRIPLES_TABLE + " t " +
				//FIXME: does this extra condition speed things up?:
				"WHERE dep1.obj > 0" + // only applies to resources
				" AND dep1.obj = t.subj" +
				" AND t.pred = " + _sail.rdfTypeId +
				" AND t.obj = " + _sail.rdfsResourceId +
				" AND dep1.id <> t.id");
	}

	/* aaa rdfs:subPropertyOf bbb && bbb rdfs:subPropertyOf ccc -->
	 * aaa rdfs:subPropertyOf ccc
	 */
	protected void _addRuleRdfs5Dependencies()
		throws SQLException
	{
		// aaa rdfs:subPropertyOf bbb in ALL_NEW_TRIPLES_TABLE:
		_rdbms.executeUpdate(
				"INSERT INTO " + DEPEND_TABLE +
				" SELECT t.id, dep1.id, dep2.id FROM " +
				ALL_NEW_TRIPLES_TABLE + " dep1, " +
				TRIPLES_TABLE + " dep2, " +
				TRIPLES_TABLE + " t " +
				"WHERE dep1.pred = " + _sail.rdfsSubPropertyOfId +
				" AND dep2.pred = " + _sail.rdfsSubPropertyOfId +
				" AND t.pred = " + _sail.rdfsSubPropertyOfId +
				" AND dep1.subj = t.subj" +
				" AND dep1.obj = dep2.subj" +
				" AND dep2.obj = t.obj" +
				" AND dep1.id <> t.id" +
				" AND dep2.id <> t.id");

		// bbb rdfs:subPropertyOf ccc in ALL_NEW_TRIPLES_TABLE:
		_rdbms.executeUpdate(
				"INSERT INTO " + DEPEND_TABLE +
				" SELECT t.id, dep1.id, dep2.id FROM " +
				TRIPLES_TABLE + " dep1, " +
				ALL_NEW_TRIPLES_TABLE + " dep2, " +
				TRIPLES_TABLE + " t " +
				"WHERE dep1.pred = " + _sail.rdfsSubPropertyOfId +
				" AND dep2.pred = " + _sail.rdfsSubPropertyOfId +
				" AND t.pred = " + _sail.rdfsSubPropertyOfId +
				" AND dep1.subj = t.subj" +
				" AND dep1.obj = dep2.subj" +
				" AND dep2.obj = t.obj" +
				" AND dep1.id <> t.id" +
				" AND dep2.id <> t.id");
	}

	/* xxx rdf:type rdf:Property --> xxx rdfs:subPropertyOf xxx */
	protected void _addRuleRdfs6Dependencies()
		throws SQLException
	{
		_rdbms.executeUpdate(
				"INSERT INTO " + DEPEND_TABLE + 
				" SELECT t.id, dep1.id, 0 FROM " +
				ALL_NEW_TRIPLES_TABLE + " dep1, " +
				TRIPLES_TABLE + " t " +
				"WHERE dep1.pred = " + _sail.rdfTypeId +
				" AND dep1.obj = " + _sail.rdfPropertyId +
				" AND t.pred = " + _sail.rdfsSubPropertyOfId +
				" AND dep1.subj = t.subj " +
				" AND t.subj = t.obj ");
	}

	/* xxx aaa yyy && aaa rdfs:subPropertyOf bbb --> xxx bbb yyy */
	protected void _addRuleRdfs7Dependencies()
		throws SQLException
	{
		// xxx aaa yyy in ALL_NEW_TRIPLES_TABLE:
		_rdbms.executeUpdate(
				"INSERT INTO " + DEPEND_TABLE +
				" SELECT t.id, dep1.id, dep2.id FROM " +
				ALL_NEW_TRIPLES_TABLE + " dep1, " +
				TRIPLES_TABLE + " dep2, " +
				TRIPLES_TABLE + " t " +
				"WHERE dep1.subj = t.subj" +
				" AND dep1.pred = dep2.subj" + 
				" AND dep1.obj = t.obj" +
				" AND dep2.pred = " + _sail.rdfsSubPropertyOfId +
				" AND dep2.obj = t.pred" +
				" AND dep1.id <> t.id" +
				" AND dep2.id <> t.id");

		// aaa rdfs:subPropertyOf bbb in ALL_NEW_TRIPLES_TABLE:
		_rdbms.executeUpdate(
				"INSERT INTO " + DEPEND_TABLE +
				" SELECT t.id, dep1.id, dep2.id FROM " +
				TRIPLES_TABLE + " dep1, " +
				ALL_NEW_TRIPLES_TABLE + " dep2, " +
				TRIPLES_TABLE + " t " +
				"WHERE dep1.subj = t.subj" +
				" AND dep1.pred = dep2.subj" + 
				" AND dep1.obj = t.obj" +
				" AND dep2.pred = " + _sail.rdfsSubPropertyOfId +
				" AND dep2.obj = t.pred" +
				" AND dep1.id <> t.id" +
				" AND dep2.id <> t.id");
	}

	/* xxx rdf:type rdfs:Class --> xxx rdfs:subClassOf rdfs:Resource */
	protected void _addRuleRdfs8Dependencies()
		throws SQLException
	{
		_rdbms.executeUpdate(
				"INSERT INTO " + DEPEND_TABLE + 
				" SELECT t.id, dep1.id, 0 FROM " +
				ALL_NEW_TRIPLES_TABLE + " dep1, " +
				TRIPLES_TABLE + " t " +
				"WHERE dep1.subj = t.subj" +
				" AND dep1.pred = " + _sail.rdfTypeId +
				" AND dep1.obj = " + _sail.rdfsClassId +
				" AND t.pred = " + _sail.rdfsSubClassOfId +
				" AND t.obj = " + _sail.rdfsResourceId);
	}

	/* xxx rdf:type rdfs:Class --> xxx rdfs:subClassOf xxx */
	protected void _addRuleRdfs10Dependencies()
		throws SQLException
	{
		_rdbms.executeUpdate(
				"INSERT INTO " + DEPEND_TABLE + 
				" SELECT t.id, dep1.id, 0 FROM " +
				ALL_NEW_TRIPLES_TABLE + " dep1, " +
				TRIPLES_TABLE + " t " +
				"WHERE dep1.subj = t.subj" +
				" AND dep1.pred = " + _sail.rdfTypeId +
				" AND dep1.obj = " + _sail.rdfsClassId +
				" AND t.pred = " + _sail.rdfsSubClassOfId +
				" AND t.subj = t.obj");
	}

	/* xxx rdfs:subClassOf yyy && yyy rdfs:subClassOf zzz -->
	 * xxx rdfs:subClassOf zzz
	 */
	protected void _addRuleRdfs11Dependencies()
		throws SQLException
	{
		// aaa rdfs:subClassOf bbb in ALL_NEW_TRIPLES_TABLE:
		_rdbms.executeUpdate(
				"INSERT INTO " + DEPEND_TABLE +
				" SELECT t.id, dep1.id, dep2.id FROM " +
				ALL_NEW_TRIPLES_TABLE + " dep1, " +
				TRIPLES_TABLE + " dep2, " +
				TRIPLES_TABLE + " t " +
				"WHERE dep1.pred = " + _sail.rdfsSubClassOfId +
				" AND dep2.pred = " + _sail.rdfsSubClassOfId +
				" AND t.pred = " + _sail.rdfsSubClassOfId +
				" AND dep1.subj = t.subj" +
				" AND dep1.obj = dep2.subj" +
				" AND dep2.obj = t.obj" +
				" AND dep1.id <> t.id" +
				" AND dep2.id <> t.id");

		// bbb rdfs:subClassOf ccc in ALL_NEW_TRIPLES_TABLE:
		_rdbms.executeUpdate(
				"INSERT INTO " + DEPEND_TABLE +
				" SELECT t.id, dep1.id, dep2.id FROM " +
				TRIPLES_TABLE + " dep1, " +
				ALL_NEW_TRIPLES_TABLE + " dep2, " +
				TRIPLES_TABLE + " t " +
				"WHERE dep1.pred = " + _sail.rdfsSubClassOfId +
				" AND dep2.pred = " + _sail.rdfsSubClassOfId +
				" AND t.pred = " + _sail.rdfsSubClassOfId +
				" AND dep1.subj = t.subj" +
				" AND dep1.obj = dep2.subj" +
				" AND dep2.obj = t.obj" +
				" AND dep1.id <> t.id" +
				" AND dep2.id <> t.id");
	}

	/* xxx rdfs:subClassOf yyy && aaa rdf:type xxx --> aaa rdf:type yyy */
	protected void _addRuleRdfs9Dependencies()
		throws SQLException
	{
		// xxx rdfs:subClassOf yyy in ALL_NEW_TRIPLES_TABLE:
		_rdbms.executeUpdate(
				"INSERT INTO " + DEPEND_TABLE +
				" SELECT t.id, dep1.id, dep2.id FROM " +
				ALL_NEW_TRIPLES_TABLE + " dep1, " +
				TRIPLES_TABLE + " dep2, " +
				TRIPLES_TABLE + " t " +
				"WHERE dep1.subj = dep2.obj" +
				" AND dep1.pred = " + _sail.rdfsSubClassOfId +
				" AND dep1.obj = t.obj" +
				" AND dep2.subj = t.subj" +
				" AND dep2.pred = " + _sail.rdfTypeId +
				" AND t.pred = " + _sail.rdfTypeId +
				" AND dep2.id <> t.id");

		// aaa rdf:type xxx in ALL_NEW_TRIPLES_TABLE:
		_rdbms.executeUpdate(
				"INSERT INTO " + DEPEND_TABLE +
				" SELECT t.id, dep1.id, dep2.id FROM " +
				TRIPLES_TABLE + " dep1, " +
				ALL_NEW_TRIPLES_TABLE + " dep2, " +
				TRIPLES_TABLE + " t " +
				"WHERE dep1.subj = dep2.obj" +
				" AND dep1.pred = " + _sail.rdfsSubClassOfId +
				" AND dep1.obj = t.obj" +
				" AND dep2.subj = t.subj" +
				" AND dep2.pred = " + _sail.rdfTypeId +
				" AND t.pred = " + _sail.rdfTypeId +
				" AND dep2.id <> t.id");
	}

	/* xxx rdf:type rdfs:ContainerMembershipProperty -->
	 * xxx rdfs:subPropertyOf rdfs:member */
	protected void _addRuleRdfs12Dependencies()
		throws SQLException
	{
		_rdbms.executeUpdate(
				"INSERT INTO " + DEPEND_TABLE + 
				" SELECT t.id, dep1.id, 0 FROM " +
				ALL_NEW_TRIPLES_TABLE + " dep1, " +
				TRIPLES_TABLE + " t " +
				"WHERE dep1.subj = t.subj" +
				" AND dep1.pred = " + _sail.rdfTypeId +
				" AND dep1.obj = " + _sail.rdfsContainerMembershipPropertyId +
				" AND t.pred = " + _sail.rdfsSubPropertyOfId +
				" AND t.obj = " + _sail.rdfsMemberId);
	}

	/* xxx rdf:type rdfs:Datatype --> xxx rdfs:subClassOf rdfs:Literal */
	protected void _addRuleRdfs13Dependencies()
		throws SQLException
	{
		_rdbms.executeUpdate(
				"INSERT INTO " + DEPEND_TABLE + 
				" SELECT t.id, dep1.id, 0 FROM " +
				ALL_NEW_TRIPLES_TABLE + " dep1, " +
				TRIPLES_TABLE + " t " +
				"WHERE dep1.subj = t.subj" +
				" AND dep1.pred = " + _sail.rdfTypeId +
				" AND dep1.obj = " + _sail.rdfsDatatypeId +
				" AND t.pred = " + _sail.rdfsSubClassOfId +
				" AND t.obj = " + _sail.rdfsLiteralId);
	}

	/* xxx rdf:_* yyy --> rdf:_* rdf:type rdfs:ContainerMembershipProperty */
	protected void _addRuleX1Dependencies()
		throws SQLException
	{
		int rdfNsId = _sail._getNamespaceId(RDF.NAMESPACE);

		if (rdfNsId == 0) {
			// Namespace not used by any resource.
			return;
		}

		// Create like pattern matching localnames starting with an underscore
		String likePattern;
		if (_rdbms.getSearchStringEscape() != null) {
			// Use default rdbms escape character
			likePattern = "'" + _rdbms.getSearchStringEscape() + "_%' ";
		}
		else if (_rdbms.supportsLikeEscapeClause()) {
			// Specify backslash as escape character
			likePattern = "'\\_%' ESCAPE '\\' ";
		}
		else {
			throw new SQLException("Unable to create like pattern; no escape character available");
		}

		_rdbms.executeUpdate(
				"INSERT INTO " + DEPEND_TABLE + 
				" SELECT t.id, dep1.id, 0 FROM " +
					ALL_NEW_TRIPLES_TABLE + " dep1, " +
					TRIPLES_TABLE + " t, " +
					RESOURCES_TABLE + " r " +
				"WHERE dep1.pred = t.subj" +
				" AND t.pred = " + _sail.rdfTypeId +
				" AND t.obj = " + _sail.rdfsContainerMembershipPropertyId +
				" AND dep1.pred = r.id " +
				" AND r.namespace = " + rdfNsId +
				" AND r.localname LIKE " + likePattern);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy