package de.unikiel.inf.comsys.neo4j.inference.rules; /* * #%L * neo4j-sparql-extension * %% * Copyright (C) 2014 Niclas Hoyer * %% * 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, either version 3 of the * License, or (at your option) any later version. * * 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, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import java.util.List; import org.openrdf.model.URI; import org.openrdf.query.algebra.QueryModelNode; import org.openrdf.query.algebra.StatementPattern; import org.openrdf.query.algebra.Union; import org.openrdf.query.algebra.Var; /** * A rule that transforms a statement pattern according to the * InverseObjectProperties OWL-2 Axiom. * * @see * <a href="http://www.w3.org/TR/owl2-semantics/#Object_Property_Expression_Axioms"> * OWL-2 property expression axioms * </a> */ public class InverseObjectProperties extends AbstractRule { private final String op1; private final String op2; /** * Create a new inverse properties rule with two inverse properties. * * @param op1 a property * @param op2 a property */ public InverseObjectProperties(String op1, String op2) { this.op1 = op1; this.op2 = op2; } /** * Returns true if this rule is applicable to a node. * * @param node to a node * @return true if the rule is applicable, false otherwise */ @Override public boolean canApply(StatementPattern node) { String op = getPredicate(node); // check if the predicate of the statement pattern matches one // or both rule predicates return op != null && (op.equals(op1) || op.equals(op2)); } /** * Transform a statement pattern according to OWL-2 inverse properties * axiom. * * @param node the node to transform * @return list of nodes to visit next */ @Override public List<QueryModelNode> apply(StatementPattern node) { List<QueryModelNode> next = newNextList(); Var s = node.getSubjectVar(); Var p = node.getPredicateVar(); Var o = node.getObjectVar(); Var c = node.getContextVar(); URI uri = (URI) p.getValue(); String op = uri.stringValue(); Var p2; // check if need to replace with op1 or op2 if (op.equals(op1)) { p2 = new ConstVar(vf.createURI(op2)); } else { p2 = new ConstVar(vf.createURI(op1)); } StatementPattern left = node.clone(); // switch subject and object and replace predicate StatementPattern right = new StatementPattern(o, p2, s, c); node.replaceWith(new Union(left, right)); next.add(left); next.add(right); return next; } @Override public String toString() { return "InverseObjectProperties(<" + op1 + "> <" + op2 + ">)"; } }