blob: a71aaaa029182fedd1a676bed2a13b19c08434c2 [file] [log] [blame]
package org.apache.rya.rdftriplestore.inference;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
import org.apache.rya.api.utils.NullableStatementImpl;
import org.apache.rya.rdftriplestore.utils.FixedStatementPattern;
import org.apache.rya.rdftriplestore.utils.TransitivePropertySP;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.model.vocabulary.OWL;
import org.eclipse.rdf4j.model.vocabulary.RDF;
import org.eclipse.rdf4j.model.vocabulary.RDFS;
import org.eclipse.rdf4j.model.vocabulary.SESAME;
import org.eclipse.rdf4j.query.algebra.StatementPattern;
import org.eclipse.rdf4j.query.algebra.Var;
/**
* All predicates are changed
* Class SubPropertyOfVisitor
* Date: Mar 29, 2011
* Time: 11:28:34 AM
*/
public class SameAsVisitor extends AbstractInferVisitor {
public SameAsVisitor(RdfCloudTripleStoreConfiguration conf, InferenceEngine inferenceEngine) {
super(conf, inferenceEngine);
include = conf.isInferSameAs();
}
public void meet(StatementPattern sp) throws Exception {
if (!include) {
return;
}
if (sp instanceof FixedStatementPattern || sp instanceof TransitivePropertySP || sp instanceof DoNotExpandSP) {
return; //already inferred somewhere else
}
final Var predVar = sp.getPredicateVar();
//do not know when things are null
if (predVar == null) {
return;
}
meetSP(sp);
}
@Override
protected void meetSP(StatementPattern node) throws Exception {
StatementPattern sp = node.clone();
final Var predVar = sp.getPredicateVar();
boolean shouldExpand = true;
if (predVar.hasValue()){
IRI pred = (IRI) predVar.getValue();
String predNamespace = pred.getNamespace();
shouldExpand = !pred.equals(OWL.SAMEAS) &&
!RDF.NAMESPACE.equals(predNamespace) &&
!SESAME.NAMESPACE.equals(predNamespace) &&
!RDFS.NAMESPACE.equals(predNamespace);
}
final Var objVar = sp.getObjectVar();
final Var subjVar = sp.getSubjectVar();
final Var cntxtVar = sp.getContextVar();
if (shouldExpand
&& !EXPANDED.equals(cntxtVar) && !(objVar == null) && !(subjVar == null)){
if (objVar.getValue() == null) {
Value subjVarValue = subjVar.getValue();
if (subjVarValue instanceof Resource){
Set<Resource> uris = inferenceEngine.findSameAs((Resource)subjVar.getValue(), getVarValue(cntxtVar));
if (uris.size() > 1){
InferJoin join = getReplaceJoin(uris, true, subjVar, objVar, predVar, cntxtVar);
node.replaceWith(join);
}
}
}
else if (subjVar.getValue() == null) {
Value objVarValue = objVar.getValue();
if (objVarValue instanceof Resource){
Set<Resource> uris = inferenceEngine.findSameAs((Resource)objVar.getValue(), getVarValue(cntxtVar));
if (uris.size() > 1){
InferJoin join = getReplaceJoin(uris, false, subjVar, objVar, predVar, cntxtVar);
node.replaceWith(join);
}
}
}
else {
// both subj and pred are set and should be expanded
Set<Resource> subjURIs = new HashSet<Resource>();
Set<Resource> objURIs = new HashSet<Resource>();
// TODO I don't like these checks -- is there a better way to do this?
Value objVarValue = objVar.getValue();
if (objVarValue instanceof Resource){
objURIs = inferenceEngine.findSameAs((Resource)objVar.getValue(), getVarValue(cntxtVar));
}
Value subjVarValue = subjVar.getValue();
if (subjVarValue instanceof Resource){
subjURIs = inferenceEngine.findSameAs((Resource)subjVar.getValue(), getVarValue(cntxtVar));
}
InferJoin finalJoin = null;
// expand subj first
if (subjURIs.size() > 1){
finalJoin = getReplaceJoin(subjURIs, true, subjVar, objVar, predVar, cntxtVar);
}
// now expand the obj
if (objURIs.size() > 1){
// if we already expanded the subj
if (finalJoin != null){
// we know what this is since we created it
DoNotExpandSP origStatement = (DoNotExpandSP) finalJoin.getRightArg();
String s = UUID.randomUUID().toString();
Var dummyVar = new Var(s);
StatementPattern origDummyStatement = new DoNotExpandSP(origStatement.getSubjectVar(), origStatement.getPredicateVar(), dummyVar, cntxtVar);
FixedStatementPattern fsp = new FixedStatementPattern(dummyVar, new Var("c-" + s, OWL.SAMEAS), objVar, cntxtVar);
for (Resource sameAs : objURIs){
NullableStatementImpl newStatement = new NullableStatementImpl(sameAs, OWL.SAMEAS,
objVar.getValue(), getVarValue(cntxtVar));
fsp.statements.add(newStatement);
}
InferJoin interimJoin = new InferJoin(fsp, origDummyStatement);
finalJoin = new InferJoin(finalJoin.getLeftArg(), interimJoin);
}
else {
finalJoin = getReplaceJoin(objURIs, false, subjVar, objVar, predVar, cntxtVar);
}
}
if (finalJoin != null){
node.replaceWith(finalJoin);
}
}
}
}
private InferJoin getReplaceJoin(Set<Resource> uris, boolean subSubj, Var subjVar, Var objVar, Var predVar, Var cntxtVar){
String s = UUID.randomUUID().toString();
Var dummyVar = new Var(s);
StatementPattern origStatement;
Var subVar;
if (subSubj){
subVar = subjVar;
origStatement = new DoNotExpandSP(dummyVar, predVar, objVar, cntxtVar);
}
else {
subVar = objVar;
origStatement = new DoNotExpandSP(subjVar, predVar, dummyVar, cntxtVar);
}
FixedStatementPattern fsp = new FixedStatementPattern(dummyVar, new Var("c-" + s, OWL.SAMEAS), subVar, cntxtVar);
for (Resource sameAs : uris){
NullableStatementImpl newStatement = new NullableStatementImpl(sameAs, OWL.SAMEAS,
subVar.getValue(), getVarValue(cntxtVar));
fsp.statements.add(newStatement);
}
InferJoin join = new InferJoin(fsp, origStatement);
join.getProperties().put(InferConstants.INFERRED, InferConstants.TRUE);
return join;
}
protected Resource getVarValue(Var var) {
if (var == null)
return null;
else
return (Resource)var.getValue();
}
}