📄 rdfmtinferencer.java
字号:
/* Sesame - Storage and Querying architecture for RDF and RDF Schema * Copyright (C) 2001-2005 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.biz/ * 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.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import org.openrdf.util.log.ThreadLog;import org.openrdf.vocabulary.RDF;import org.openrdf.sesame.sail.SailInternalException;/** * Inferencer using the rules from the RDF Semantics Recommendation (10 * February 2004). See http://www.w3.org/TR/2004/REC-rdf-mt-20040210/ * This inferencer operates directly on the database used by the * RdfSchemaRepository. **/public class RdfMTInferencer implements TableNames {/*-------------------------------------+| Constants |+-------------------------------------*/ // Some constants used to map rule numbers to indexes in arrays private static final int Rdf1 = 0; private static final int Rdfs2_1 = 1; private static final int Rdfs2_2 = 2; private static final int Rdfs3_1 = 3; private static final int Rdfs3_2 = 4; private static final int Rdfs4a = 5; private static final int Rdfs4b = 6; private static final int Rdfs5_1 = 7; private static final int Rdfs5_2 = 8; private static final int Rdfs6 = 9; private static final int Rdfs7_1 = 10; private static final int Rdfs7_2 = 11; private static final int Rdfs8 = 12; private static final int Rdfs9_1 = 13; private static final int Rdfs9_2 = 14; private static final int Rdfs10 = 15; private static final int Rdfs11_1 = 16; private static final int Rdfs11_2 = 17; private static final int Rdfs12 = 18; private static final int Rdfs13 = 19; private static final int RX1 = 20; private static final int RULECOUNT = 21; private static final String[] RULENAMES = { "Rdf1", "Rdfs2_1", "Rdfs2_2", "Rdfs3_1", "Rdfs3_2", "Rdfs4a", "Rdfs4b", "Rdfs5_1", "Rdfs5_2", "Rdfs6", "Rdfs7_1", "Rdfs7_2", "Rdfs8", "Rdfs9_1", "Rdfs9_2", "Rdfs10", "Rdfs11_1", "Rdfs11_2", "Rdfs12", "Rdfs13", "RX1"};/*This inferencer makes use of the fact that results of a rule don't triggerall other inference rules. I.e: if one rule infers a new subClassOfstatement, this will only trigger rules whose precendents can match sucha statement.The following table shows the dependencies between the rules. An 'x' in thistable means that the rule on this row triggers the rule in that column. | triggers rule:rule:| 1 2_1 2_2 3_1 3_2 4a 4b 5_1 5_2 6 7_1 7_2 8 9_1 9_2 10 11_1 11_2 12 13 X1-----+--------------------------------------------------------------------------------1 | - x - x - x - - - x x - - - x - - - - - -2_1 | - x - x - - - - - x x - x - x x - - x x -2_2 | - x - x - - - - - x x - x - x x - - x x -3_1 | - x - x - - - - - x x - x - x x - - x x -3_2 | - x - x - - - - - x x - x - x x - - x x -4a | - x - x - - - - - - x - - - x - - - - - -4b | - x - x - - - - - - x - - - x - - - - - -5_1 | - - - - - - - x x - x x - - - - - - - - -5_2 | - - - - - - - x x - x x - - - - - - - - -6 | - x - x - - - - - - x - - - - - - - - - -7_1 | - x x x x - - x x x x x x x x x x x x x x7_2 | - x x x x - - x x x x x x x x x x x x x x8 | - x - x - - - - - - x - - x - - x x - - -9_1 | - - - x - - - - - x x - x - x x - - x x -9_2 | - - - x - - - - - x x - x - x x - - x x -10 | - x - x - - - - - - x - - - - - - - - - -11_1 | - - - - - - - - - - x - - x - - x x - - -11_2 | - - - - - - - - - - x - - x - - x x - - -12 | - x - x - - x x x - x x - - - - - - - - -13 | - x - - - - - - - - x - - x - - x x - - -X1 | - x - x - - - - - - x - - - x - - - x - -*/ private static final boolean _ = false; private static final boolean X = true; private static final boolean[][] TRIGGERS = {// 1 2_2 3_2 4b 5_2 7_1 8 9_2 11_1 12 X1// 2_1 3_1 4a 5_1 6 7_2 9_1 10 11_2 13 { _, X, _, X, _, X, _, _, _, X, X, _, _, _, X, _, _, _, _, _, _},// 1 { _, X, _, X, _, _, _, _, _, X, X, _, X, _, X, X, _, _, X, X, _},// 2_1 { _, X, _, X, _, _, _, _, _, X, X, _, X, _, X, X, _, _, X, X, _},// 2_2 { _, X, _, X, _, _, _, _, _, X, X, _, X, _, X, X, _, _, X, X, _},// 3_1 { _, X, _, X, _, _, _, _, _, X, X, _, X, _, X, X, _, _, X, X, _},// 3_2 { _, X, _, X, _, _, _, _, _, _, X, _, _, _, X, _, _, _, _, _, _},// 4a { _, X, _, X, _, _, _, _, _, _, X, _, _, _, X, _, _, _, _, _, _},// 4b { _, _, _, _, _, _, _, X, X, _, X, X, _, _, _, _, _, _, _, _, _},// 51 { _, _, _, _, _, _, _, X, X, _, X, X, _, _, _, _, _, _, _, _, _},// 52 { _, X, _, X, _, _, _, _, _, _, X, _, _, _, _, _, _, _, _, _, _},// 6 { _, X, X, X, X, _, _, X, X, X, X, X, X, X, X, X, X, X, X, X, X},// 7_1 { _, X, X, X, X, _, _, X, X, X, X, X, X, X, X, X, X, X, X, X, X},// 7_2 { _, X, _, X, _, _, _, _, _, _, X, _, _, X, _, _, X, X, _, _, _},// 8 { _, _, _, X, _, _, _, _, _, X, X, _, X, _, X, X, _, _, X, X, _},// 9_1 { _, _, _, X, _, _, _, _, _, X, X, _, X, _, X, X, _, _, X, X, _},// 9_2 { _, X, _, X, _, _, _, _, _, _, X, _, _, _, _, _, _, _, _, _, _},// 10 { _, _, _, _, _, _, _, _, _, _, X, _, _, X, _, _, X, X, _, _, _},// 11_1 { _, _, _, _, _, _, _, _, _, _, X, _, _, X, _, _, X, X, _, _, _},// 11_2 { _, X, _, X, _, _, X, X, X, _, X, X, _, _, _, _, _, _, _, _, _},// 12 { _, X, _, _, _, _, _, _, _, _, X, _, _, X, _, _, X, X, _, _, _},// 13 { _, X, _, X, _, _, _, _, _, _, X, _, _, _, X, _, _, _, X, _, _},// X1 };/*-------------------------------------+| Variables |+-------------------------------------*/ private RdfSchemaRepository _repository; private RDBMS _rdbms; private Connection _insertCon; private PreparedStatement _insertSt; /** Flags indicating which rules should be evaluated. **/ private boolean[] _checkRule = new boolean[RULECOUNT]; /** Flags indicating which rules should be evaluated next iteration. **/ private boolean[] _checkRuleNextIter = new boolean[RULECOUNT]; // Variables for optimization statistics private int _totalInferred = 0; // number of inferred statements per rule. private int[] _ruleCount = new int[RULECOUNT]; // total processing time per rule. private long[] _ruleTime = new long[RULECOUNT];/*-------------------------------------+| Constructors |+-------------------------------------*/ public RdfMTInferencer(RdfSchemaRepository repository, RDBMS rdbms) { _repository = repository; _rdbms = rdbms; }/*-------------------------------------+| Methods |+-------------------------------------*/ /** * Prepares a connection and a PreparedStatement for adding * rows to the INFERRED_TABLE. **/ private void _prepareInsertConnection() throws SQLException { _insertCon = _rdbms.getConnection(); _insertCon.setAutoCommit(false); _insertSt = _insertCon.prepareStatement( "INSERT INTO " + INFERRED_TABLE + " VALUES(?, ?, ?, ?, ?)"); // All statements are implicit here: _insertSt.setBoolean(5, false); } /** * Closes the connection that was prepared in _prepareInsertConnection(). * If <tt>mustCommit</tt> is true, the started transaction is committed * first. **/ private void _closeInsertConnection(boolean mustCommit) throws SQLException { if (mustCommit) { /* int[] results = _insertSt.executeBatch(); for (int i = 0; i < results.length; i++) { if (results[i] == Statement.EXECUTE_FAILED) { throw new SQLException("Failed to add one or more rows to table " + INFERRED_TABLE); } } */ _insertCon.commit(); } _insertSt.close(); _insertCon.close(); } public void initialize() { try { // As defined in the RDF MT: add a number of default statements // concerning the definition of RDF and RDF Schema primitives _addAxioms(); // ...and apply the inference rules to them. doInferencing(); } catch (SQLException e) { throw new SailInternalException(e); } } private void _addAxioms() throws SQLException { ThreadLog.trace("adding axioms"); // Insert all axioms into INFERRED_TABLE _prepareInsertConnection(); // RDF axiomatic triples (from RDF Semantics, section 3.1): _insertAxiom(_repository.rdfTypeId, _repository.rdfTypeId, _repository.rdfPropertyId); _insertAxiom(_repository.rdfSubjectId, _repository.rdfTypeId, _repository.rdfPropertyId); _insertAxiom(_repository.rdfPredicateId, _repository.rdfTypeId, _repository.rdfPropertyId); _insertAxiom(_repository.rdfObjectId, _repository.rdfTypeId, _repository.rdfPropertyId); _insertAxiom(_repository.rdfFirstId, _repository.rdfTypeId, _repository.rdfPropertyId); _insertAxiom(_repository.rdfRestId, _repository.rdfTypeId, _repository.rdfPropertyId); _insertAxiom(_repository.rdfValueId, _repository.rdfTypeId, _repository.rdfPropertyId); _insertAxiom(_repository.rdfNilId, _repository.rdfTypeId, _repository.rdfListId); // RDFS axiomatic triples (from RDF Semantics, section 4.1): _insertAxiom(_repository.rdfTypeId, _repository.rdfsDomainId, _repository.rdfsResourceId); _insertAxiom(_repository.rdfsDomainId, _repository.rdfsDomainId, _repository.rdfPropertyId); _insertAxiom(_repository.rdfsRangeId, _repository.rdfsDomainId, _repository.rdfPropertyId); _insertAxiom(_repository.rdfsSubPropertyOfId, _repository.rdfsDomainId, _repository.rdfPropertyId); _insertAxiom(_repository.rdfsSubClassOfId, _repository.rdfsDomainId, _repository.rdfsClassId); _insertAxiom(_repository.rdfSubjectId, _repository.rdfsDomainId, _repository.rdfStatementId); _insertAxiom(_repository.rdfPredicateId, _repository.rdfsDomainId, _repository.rdfStatementId); _insertAxiom(_repository.rdfObjectId, _repository.rdfsDomainId, _repository.rdfStatementId); _insertAxiom(_repository.rdfsMemberId, _repository.rdfsDomainId, _repository.rdfsResourceId); _insertAxiom(_repository.rdfFirstId, _repository.rdfsDomainId, _repository.rdfListId); _insertAxiom(_repository.rdfRestId, _repository.rdfsDomainId, _repository.rdfListId); _insertAxiom(_repository.rdfsSeeAlsoId, _repository.rdfsDomainId, _repository.rdfsResourceId); _insertAxiom(_repository.rdfsIsDefinedById, _repository.rdfsDomainId, _repository.rdfsResourceId); _insertAxiom(_repository.rdfsCommentId, _repository.rdfsDomainId, _repository.rdfsResourceId); _insertAxiom(_repository.rdfsLabelId, _repository.rdfsDomainId, _repository.rdfsResourceId); _insertAxiom(_repository.rdfValueId, _repository.rdfsDomainId, _repository.rdfsResourceId); _insertAxiom(_repository.rdfTypeId, _repository.rdfsRangeId, _repository.rdfsClassId); _insertAxiom(_repository.rdfsDomainId, _repository.rdfsRangeId, _repository.rdfsClassId); _insertAxiom(_repository.rdfsRangeId, _repository.rdfsRangeId, _repository.rdfsClassId); _insertAxiom(_repository.rdfsSubPropertyOfId, _repository.rdfsRangeId, _repository.rdfPropertyId); _insertAxiom(_repository.rdfsSubClassOfId, _repository.rdfsRangeId, _repository.rdfsClassId); _insertAxiom(_repository.rdfSubjectId, _repository.rdfsRangeId, _repository.rdfsResourceId); _insertAxiom(_repository.rdfPredicateId, _repository.rdfsRangeId, _repository.rdfsResourceId); _insertAxiom(_repository.rdfObjectId, _repository.rdfsRangeId, _repository.rdfsResourceId); _insertAxiom(_repository.rdfsMemberId, _repository.rdfsRangeId, _repository.rdfsResourceId); _insertAxiom(_repository.rdfFirstId, _repository.rdfsRangeId, _repository.rdfsResourceId); _insertAxiom(_repository.rdfRestId, _repository.rdfsRangeId, _repository.rdfListId); _insertAxiom(_repository.rdfsSeeAlsoId, _repository.rdfsRangeId, _repository.rdfsResourceId); _insertAxiom(_repository.rdfsIsDefinedById, _repository.rdfsRangeId, _repository.rdfsResourceId); _insertAxiom(_repository.rdfsCommentId, _repository.rdfsRangeId, _repository.rdfsLiteralId); _insertAxiom(_repository.rdfsLabelId, _repository.rdfsRangeId, _repository.rdfsLiteralId); _insertAxiom(_repository.rdfValueId, _repository.rdfsRangeId, _repository.rdfsResourceId); _insertAxiom(_repository.rdfAltId, _repository.rdfsSubClassOfId, _repository.rdfsContainerId); _insertAxiom(_repository.rdfBagId, _repository.rdfsSubClassOfId, _repository.rdfsContainerId); _insertAxiom(_repository.rdfSeqId, _repository.rdfsSubClassOfId, _repository.rdfsContainerId); _insertAxiom(_repository.rdfsContainerMembershipPropertyId, _repository.rdfsSubClassOfId, _repository.rdfPropertyId); _insertAxiom(_repository.rdfsIsDefinedById, _repository.rdfsSubPropertyOfId, _repository.rdfsSeeAlsoId); _insertAxiom(_repository.rdfXMLLiteralId, _repository.rdfTypeId, _repository.rdfsDatatypeId); _insertAxiom(_repository.rdfXMLLiteralId, _repository.rdfsSubClassOfId, _repository.rdfsLiteralId); _insertAxiom(_repository.rdfsDatatypeId, _repository.rdfsSubClassOfId, _repository.rdfsClassId); _closeInsertConnection(true); // Copy all axioms that are not yet in the triples table int newAxioms = _rdbms.executeUpdate( "INSERT INTO " + NEW_TRIPLES_TABLE + " " + "SELECT inf.* " + "FROM " + INFERRED_TABLE + " inf " + "LEFT JOIN " + TRIPLES_TABLE + " t ON " + "inf.subj = t.subj AND " + "inf.pred = t.pred AND " + "inf.obj = t.obj " + "WHERE " + "t.subj IS NULL"); if (newAxioms > 0) { _rdbms.copyRows(NEW_TRIPLES_TABLE, TRIPLES_TABLE); _rdbms.copyRows(NEW_TRIPLES_TABLE, ALL_NEW_TRIPLES_TABLE); } // Clear INFERRED_TABLE _rdbms.clearTable(INFERRED_TABLE); } private void _insertAxiom(int subjId, int predId, int objId) throws SQLException { _insertSt.setInt(1, _repository._getNextStatementId()); _insertSt.setInt(2, subjId); _insertSt.setInt(3, predId); _insertSt.setInt(4, objId); _insertSt.executeUpdate(); } public void doInferencing() { // initialize some vars _totalInferred = 0; int iteration = 0; // All rules needs to be checked: for (int i = 0; i < RULECOUNT; i++) { _ruleCount[i] = 0; _ruleTime[i] = 0; _checkRuleNextIter[i] = true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -