/* Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. Contact: SYSTAP, LLC DBA Blazegraph 2501 Calvert ST NW #106 Washington, DC 20008 licenses@blazegraph.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package com.bigdata.rdf.rules; import org.openrdf.model.vocabulary.RDF; import org.openrdf.model.vocabulary.RDFS; import com.bigdata.rdf.axioms.Axioms; import com.bigdata.rdf.internal.IV; import com.bigdata.rdf.internal.IVUtility; import com.bigdata.rdf.model.StatementEnum; import com.bigdata.rdf.spo.ISPO; import com.bigdata.rdf.spo.SPOFilter; import com.bigdata.rdf.vocab.Vocabulary; import com.bigdata.relation.rule.eval.ISolution; /** * Filter keeps matched triple patterns generated OUT of the database. * <p> * Note: {@link StatementEnum#Explicit} triples are always rejected by this * filter so that explicitly asserted triples will always be stored in the * database. * <p> * Note: {@link StatementEnum#Axiom}s are always rejected by this filter so * that they will be stored in the database. * * @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan Thompson</a> * @version $Id$ */ public class DoNotAddFilter<E extends ISPO> extends SPOFilter<E> { // protected static final Logger log = Logger.getLogger(DoNotAddFilter.class); // // protected static final boolean INFO = log.isInfoEnabled(); // // protected static final boolean DEBUG = log.isDebugEnabled(); /** * */ private static final long serialVersionUID = -7833182476134679170L; private final Axioms axioms; private final IV rdfType; private final IV rdfsResource; private final boolean forwardChainRdfTypeRdfsResource; /** * * @param vocab * The {@link Vocabulary} * @param axioms * The {@link Axioms}. * @param forwardChainRdfTypeRdfsResource * <code>true</code> if we generate the entailments for (x * rdf:type rdfs:Resource) when the closure of the database is * updated. */ public DoNotAddFilter(final Vocabulary vocab, final Axioms axioms, boolean forwardChainRdfTypeRdfsResource) { if (vocab == null) throw new IllegalArgumentException(); if (axioms == null) throw new IllegalArgumentException(); this.axioms = axioms; this.forwardChainRdfTypeRdfsResource = forwardChainRdfTypeRdfsResource; if (!forwardChainRdfTypeRdfsResource && axioms.isRdfSchema()) { /* * If we are not forward chaining the type resource entailments then * we want to keep those statements out of the database since they * are materialized by the backward chainer. For that purpose we * need to save off the term identifier for rdf:type and * rdfs:Resource. */ this.rdfType = vocab.get(RDF.TYPE); this.rdfsResource = vocab.get(RDFS.RESOURCE); } else { /* * These will not be used unless we are forward chaining type * resource entailments and they will not be defined unless the rdfs * axioms were specified (really, unless the RDFSVocabulary was * defined). */ this.rdfType = this.rdfsResource = null; } } public boolean isValid(Object o) { if (!canAccept(o)) { return true; } return accept((ISPO) o); } private boolean accept(final ISPO o) { final ISPO spo = (ISPO) o; if(spo.s().isLiteral()) { /* * Note: Explicitly toss out entailments that would place a * literal into the subject position. These statements can enter * the database via rdfs3 and rdfs4b. */ return false; } if (spo.getStatementType() == StatementEnum.Explicit ) { // Accept all explicit statements. return true; } // if (spo.isOverride()) { // // // Accept all statements with the override flag set. // // return true; // // } if( axioms.isAxiom(spo.s(), spo.p(), spo.o())) { /* * Reject all statements which correspond to axioms. * * Note: This will let in explicit statements that correspond to * axioms since we let in all explicit statements above. The main * thing that this does is keep axioms generated by the rules from * showing up in the database, where they convert statements from * Axiom to Inferred. */ return false; } if (!forwardChainRdfTypeRdfsResource && IVUtility.equals(spo.p(), rdfType) && IVUtility.equals(spo.o(), rdfsResource)) { // reject (?x, rdf:type, rdfs:Resource ) return false; } // Accept everything else. return true; } }