org.mindswap.pellet.jena.graph.loader.DefaultGraphLoader Maven / Gradle / Ivy
// Portions Copyright (c) 2006 - 2008, Clark & Parsia, LLC.
//
// Clark & Parsia, LLC parts of this source code are available under the terms
// of the Affero General Public License v3.
//
// Please see LICENSE.txt for full license terms, including the availability of
// proprietary exceptions.
// Questions, comments, or requests for clarification: [email protected]
//
// ---
// Portions Copyright (c) 2003 Ron Alford, Mike Grove, Bijan Parsia, Evren Sirin
// Alford, Grove, Parsia, Sirin parts of this source code are available under
// the terms of the MIT License.
//
// The MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
package org.mindswap.pellet.jena.graph.loader;
import static org.mindswap.pellet.jena.graph.loader.SimpleProperty.ANTI_SYM;
import static org.mindswap.pellet.jena.graph.loader.SimpleProperty.CARDINALITY;
import static org.mindswap.pellet.jena.graph.loader.SimpleProperty.DISJOINT;
import static org.mindswap.pellet.jena.graph.loader.SimpleProperty.IRREFLEXIVE;
import static org.mindswap.pellet.jena.graph.loader.SimpleProperty.SELF;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.mindswap.pellet.KnowledgeBase;
import org.mindswap.pellet.PelletOptions;
import org.mindswap.pellet.PropertyType;
import org.mindswap.pellet.Role;
import org.mindswap.pellet.exceptions.InternalReasonerException;
import org.mindswap.pellet.exceptions.UnsupportedFeatureException;
import org.mindswap.pellet.jena.BuiltinTerm;
import org.mindswap.pellet.jena.JenaUtils;
import org.mindswap.pellet.jena.vocabulary.OWL2;
import org.mindswap.pellet.jena.vocabulary.SWRL;
import org.mindswap.pellet.utils.ATermUtils;
import org.mindswap.pellet.utils.AnnotationClasses;
import org.mindswap.pellet.utils.Bool;
import org.mindswap.pellet.utils.QNameProvider;
import org.mindswap.pellet.utils.SetUtils;
import org.mindswap.pellet.utils.Timer;
import org.mindswap.pellet.utils.progress.ProgressMonitor;
import org.mindswap.pellet.utils.progress.SilentProgressMonitor;
import aterm.ATerm;
import aterm.ATermAppl;
import aterm.ATermList;
import com.clarkparsia.pellet.rules.model.AtomDConstant;
import com.clarkparsia.pellet.rules.model.AtomDObject;
import com.clarkparsia.pellet.rules.model.AtomDVariable;
import com.clarkparsia.pellet.rules.model.AtomIConstant;
import com.clarkparsia.pellet.rules.model.AtomIObject;
import com.clarkparsia.pellet.rules.model.AtomIVariable;
import com.clarkparsia.pellet.rules.model.BuiltInAtom;
import com.clarkparsia.pellet.rules.model.ClassAtom;
import com.clarkparsia.pellet.rules.model.DataRangeAtom;
import com.clarkparsia.pellet.rules.model.DatavaluedPropertyAtom;
import com.clarkparsia.pellet.rules.model.DifferentIndividualsAtom;
import com.clarkparsia.pellet.rules.model.IndividualPropertyAtom;
import com.clarkparsia.pellet.rules.model.Rule;
import com.clarkparsia.pellet.rules.model.RuleAtom;
import com.clarkparsia.pellet.rules.model.SameIndividualAtom;
import com.clarkparsia.pellet.vocabulary.BuiltinNamespace;
import com.hp.hpl.jena.graph.Factory;
import com.hp.hpl.jena.graph.Graph;
import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.graph.Triple;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.util.iterator.ClosableIterator;
import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS;
/**
*
* Title:
*
*
* Description:
*
*
* Copyright: Copyright (c) 2008
*
*
* Company: Clark & Parsia, LLC.
*
*
* @author Evren Sirin
*/
public class DefaultGraphLoader implements GraphLoader {
public static final Logger log = Logger
.getLogger( DefaultGraphLoader.class
.getName() );
protected static final Node[] TBOX_TYPES;
protected static final Node[] TBOX_PREDICATES;
static {
ArrayList predicates = new ArrayList();
ArrayList types = new ArrayList();
for( BuiltinTerm builtinTerm : BuiltinTerm.values() ) {
if( builtinTerm.isABox() || builtinTerm.isSyntax() ) {
continue;
}
if( builtinTerm.isPredicate() ) {
predicates.add( builtinTerm.getNode() );
}
else {
types.add( builtinTerm.getNode() );
}
}
TBOX_PREDICATES = predicates.toArray( new Node[predicates.size()] );
TBOX_TYPES = types.toArray( new Node[types.size()] );
}
private static final EnumSet OWL_MEMBERS_TYPES = EnumSet
.of(
BuiltinTerm.OWL_AllDifferent,
BuiltinTerm.OWL2_AllDisjointClasses,
BuiltinTerm.OWL2_AllDisjointProperties );
private static final Graph EMPTY_GRAPH = Factory.createGraphMem();
public static QNameProvider qnames = new QNameProvider();
protected KnowledgeBase kb;
protected Graph graph;
protected Map terms;
protected Map lists;
protected Set anonDatatypes;
protected Map naryDisjoints;
private Map simpleProperties;
private Set unsupportedFeatures;
private boolean loadABox = true;
private boolean preprocessTypeTriples = true;
protected ProgressMonitor monitor = new SilentProgressMonitor();
public DefaultGraphLoader() {
clear();
}
/**
* {@inheritDoc}
*/
public void setProgressMonitor(ProgressMonitor monitor) {
if( monitor == null ) {
this.monitor = new SilentProgressMonitor();
}
else {
this.monitor = monitor;
}
}
/**
* {@inheritDoc}
*/
public void setGraph(Graph graph) {
this.graph = graph;
}
/**
* {@inheritDoc}
*/
public Graph getGraph() {
return graph;
}
/**
* {@inheritDoc}
*/
public Set getUnpportedFeatures() {
return unsupportedFeatures;
}
protected void addSimpleProperty(ATermAppl p, SimpleProperty why) {
simpleProperties.put( p, why );
Role role = kb.getRBox().getRole( p );
role.setForceSimple( true );
}
protected void addUnsupportedFeature(String msg) {
if( !PelletOptions.IGNORE_UNSUPPORTED_AXIOMS ) {
throw new UnsupportedFeatureException( msg );
}
if( unsupportedFeatures.add( msg ) ) {
log.warning( "Unsupported axiom: " + msg );
}
}
/**
* {@inheritDoc}
*/
public void clear() {
terms = new HashMap();
terms.put( OWL.Thing.asNode(), ATermUtils.TOP );
terms.put( OWL.Nothing.asNode(), ATermUtils.BOTTOM );
terms.put( OWL2.topDataProperty.asNode(), ATermUtils.TOP_DATA_PROPERTY );
terms.put( OWL2.bottomDataProperty.asNode(), ATermUtils.BOTTOM_DATA_PROPERTY );
terms.put( OWL2.topObjectProperty.asNode(), ATermUtils.TOP_OBJECT_PROPERTY );
terms.put( OWL2.bottomObjectProperty.asNode(), ATermUtils.BOTTOM_OBJECT_PROPERTY );
lists = new HashMap();
lists.put( RDF.nil.asNode(), ATermUtils.EMPTY_LIST );
anonDatatypes = new HashSet();
simpleProperties = new HashMap();
unsupportedFeatures = new HashSet();
naryDisjoints = new HashMap();
}
private Node getObject(Node subj, Node pred) {
ClosableIterator i = graph.find( subj, pred, null );
if( i.hasNext() ) {
Triple triple = i.next();
i.close();
return triple.getObject();
}
return null;
}
private boolean hasObject(Node subj, Node pred, Node obj) {
return graph.contains( subj, pred, obj );
}
private class RDFListIterator implements Iterator {
private Node list;
public RDFListIterator(Node list) {
this.list = list;
}
public boolean hasNext() {
return !list.equals( RDF.nil.asNode() );
}
public Node next() {
Node first = getFirst( list );
monitor.incrementProgress();
Node rest = getRest( list );
monitor.incrementProgress();
if( first == null || rest == null ) {
addUnsupportedFeature( "Invalid list structure: List " + list + " does not have a "
+ (first == null
? "rdf:first"
: "rdf:rest") + " property. Ignoring rest of the list." );
return null;
}
list = rest;
return first;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
protected Node getFirst(Node list) {
return getObject( list, RDF.first.asNode() );
}
protected Node getRest(Node list) {
return getObject( list, RDF.rest.asNode() );
}
protected ATermList createList(Node node) {
if( lists.containsKey( node ) ) {
return lists.get( node );
}
ATermList list = createList( new RDFListIterator( node ) );
lists.put( node, list );
return list;
}
protected ATermList createList(RDFListIterator i) {
if( !i.hasNext() ) {
return ATermUtils.EMPTY_LIST;
}
Node node = i.next();
if( node == null ) {
return ATermUtils.EMPTY_LIST;
}
ATermAppl first = node2term( node );
ATermList rest = createList( i );
ATermList list = ATermUtils.makeList( first, rest );
return list;
}
protected boolean isRestriction(Node node) {
return getObject( node, OWL.onProperty.asNode() ) != null;
}
protected ATermAppl createRestriction(Node node) throws UnsupportedFeatureException {
Node restrictionType = null;
Node p = null;
Node filler = null;
Node qualification = null;
Bool isObjectRestriction = Bool.UNKNOWN;
ClosableIterator i = graph.find( node, null, null );
while( i.hasNext() ) {
monitor.incrementProgress();
Triple t = i.next();
Node pred = t.getPredicate();
BuiltinTerm builtinTerm = BuiltinTerm.find( pred );
if( builtinTerm == null ) {
continue;
}
switch ( builtinTerm ) {
case OWL_someValuesFrom:
case OWL_allValuesFrom:
case OWL_cardinality:
case OWL_minCardinality:
case OWL_maxCardinality:
case OWL_hasValue:
case OWL2_hasSelf:
case OWL2_qualifiedCardinality:
case OWL2_minQualifiedCardinality:
case OWL2_maxQualifiedCardinality:
restrictionType = pred;
filler = t.getObject();
break;
case OWL_onProperty:
p = t.getObject();
break;
case RDF_type:
if( t.getObject().equals( OWL2.SelfRestriction.asNode() ) ) {
restrictionType = OWL2.hasSelf.asNode();
filler = JenaUtils.XSD_BOOLEAN_TRUE.asNode();
}
break;
case OWL2_onClass:
isObjectRestriction = Bool.TRUE;
qualification = t.getObject();
break;
case OWL2_onDataRange:
isObjectRestriction = Bool.FALSE;
qualification = t.getObject();
break;
default:
break;
}
}
i.close();
return createRestriction( restrictionType, p, filler, qualification, isObjectRestriction );
}
protected ATermAppl createRestriction(Node restrictionType, Node p, Node filler,
Node qualification, Bool isObjectRestriction) throws UnsupportedFeatureException {
ATermAppl aTerm = ATermUtils.TOP;
if( restrictionType == null || filler == null ) {
addUnsupportedFeature( "Skipping invalid restriction" );
return aTerm;
}
ATermAppl pt = node2term( p );
if( restrictionType.equals( OWL2.hasSelf.asNode() ) ) {
Object value = null;
try {
value = kb.getDatatypeReasoner().getValue( node2term( filler ) );
}
catch (Exception e) {
log.log(Level.FINE, "Invalid hasSelf value: " + filler, e );
}
if( Boolean.TRUE.equals( value ) ) {
aTerm = ATermUtils.makeSelf( pt );
defineObjectProperty( pt );
addSimpleProperty( pt, SELF );
}
else {
addUnsupportedFeature( "Invalid value for " + OWL2.hasSelf.getLocalName()
+ " restriction. Expecting \"true\"^^xsd:boolean but found: " + filler );
}
}
else if( restrictionType.equals( OWL.hasValue.asNode() ) ) {
ATermAppl ot = node2term( filler );
if( filler.isLiteral() ) {
defineDatatypeProperty( pt );
}
else {
defineObjectProperty( pt );
defineIndividual( ot );
}
aTerm = ATermUtils.makeHasValue( pt, ot );
}
else if( restrictionType.equals( OWL.allValuesFrom.asNode() ) ) {
ATermAppl ot = node2term( filler );
if( kb.isClass( ot ) ) {
defineObjectProperty( pt );
}
else if( kb.isDatatype( ot ) ) {
defineDatatypeProperty( pt );
}
aTerm = ATermUtils.makeAllValues( pt, ot );
}
else if( restrictionType.equals( OWL.someValuesFrom.asNode() ) ) {
ATermAppl ot = node2term( filler );
if( kb.isClass( ot ) ) {
defineObjectProperty( pt );
}
else if( kb.isDatatype( ot ) ) {
defineDatatypeProperty( pt );
}
aTerm = ATermUtils.makeSomeValues( pt, ot );
}
else if( restrictionType.equals( OWL.minCardinality.asNode() )
|| restrictionType.equals( OWL.maxCardinality.asNode() )
|| restrictionType.equals( OWL.cardinality.asNode() )
|| restrictionType.equals( OWL2.minQualifiedCardinality.asNode() )
|| restrictionType.equals( OWL2.maxQualifiedCardinality.asNode() )
|| restrictionType.equals( OWL2.qualifiedCardinality.asNode() ) ) {
try {
ATermAppl c = null;
if( isObjectRestriction.isTrue() ) {
c = node2term( qualification );
defineObjectProperty( pt );
}
else if( isObjectRestriction.isFalse() ) {
c = node2term( qualification );
defineDatatypeProperty( pt );
}
else {
PropertyType propType = kb.getPropertyType( pt );
if( propType == PropertyType.OBJECT ) {
c = ATermUtils.TOP;
}
else if( propType == PropertyType.DATATYPE ) {
c = ATermUtils.TOP_LIT;
}
else {
defineObjectProperty( pt );
c = ATermUtils.TOP;
}
}
int cardinality =
Integer.parseInt( filler.getLiteral().getLexicalForm().trim() );
if( restrictionType.equals( OWL.minCardinality.asNode() )
|| restrictionType.equals( OWL2.minQualifiedCardinality.asNode() ) ) {
aTerm = ATermUtils.makeMin( pt, cardinality, c );
}
else if( restrictionType.equals( OWL.maxCardinality.asNode() )
|| restrictionType.equals( OWL2.maxQualifiedCardinality.asNode() ) ) {
aTerm = ATermUtils.makeMax( pt, cardinality, c );
}
else {
aTerm = ATermUtils.makeCard( pt, cardinality, c );
}
addSimpleProperty( pt, CARDINALITY );
} catch( Exception ex ) {
addUnsupportedFeature( "Invalid value for the owl:"
+ restrictionType.getLocalName() + " restriction: " + filler );
log.log( Level.WARNING, "Invalid cardinality", ex );
}
}
else {
addUnsupportedFeature( "Ignoring invalid restriction on " + p );
}
return aTerm;
}
/**
* {@inheritDoc}
*/
public ATermAppl node2term(Node node) {
ATermAppl aTerm = terms.get( node );
if( aTerm == null ) {
boolean canCache = true;
if( isRestriction( node ) ) {
aTerm = createRestriction( node );
}
else if( node.isBlank() ) {
Triple expr = getExpression( node );
if( expr != null ) {
Node exprType = expr.getPredicate();
Node exprValue = expr.getObject();
if( exprType.equals( OWL.intersectionOf.asNode() ) ) {
ATermList list = createList( exprValue );
aTerm = ATermUtils.makeAnd( list );
}
else if( exprType.equals( OWL.unionOf.asNode() ) ) {
ATermList list = createList( exprValue );
aTerm = ATermUtils.makeOr( list );
}
else if( exprType.equals( OWL.complementOf.asNode() )
|| exprType.equals( OWL2.datatypeComplementOf.asNode() ) ) {
ATermAppl complement = node2term( exprValue );
aTerm = ATermUtils.makeNot( complement );
}
else if( exprType.equals( OWL.inverseOf.asNode() ) ) {
ATermAppl inverse = node2term( exprValue );
aTerm = ATermUtils.makeInv( inverse );
}
else if( exprType.equals( OWL.oneOf.asNode() ) ) {
ATermList list = createList( exprValue );
ATermList result = ATermUtils.EMPTY_LIST;
if( list.isEmpty() ) {
aTerm = ATermUtils.BOTTOM;
}
else {
for( ATermList l = list; !l.isEmpty(); l = l.getNext() ) {
ATermAppl c = (ATermAppl) l.getFirst();
ATermAppl nominal = ATermUtils.makeValue( c );
result = result.insert( nominal );
}
aTerm = ATermUtils.makeOr( result );
}
}
else if( exprType.equals( OWL2.onDatatype.asNode() ) ) {
aTerm = parseDataRange( node, exprValue );
}
else if( exprType.equals( OWL2.onDataRange.asNode() ) ) {
aTerm = parseDataRangeLegacy( node, exprValue );
}
else if( exprType.equals( OWL2.propertyChain.asNode() ) ) {
// do nothing because we cannot return an ATermList here
}
else {
addUnsupportedFeature( "Unexpected bnode " + node + " " + expr );
}
}
else {
canCache = false;
aTerm = JenaUtils.makeATerm( node );
}
}
else {
aTerm = JenaUtils.makeATerm( node );
}
if( canCache ) {
terms.put( node, aTerm );
}
}
return aTerm;
}
protected Triple getExpression(Node node) {
for( BuiltinTerm expressionPredicate : BuiltinTerm.EXPRESSION_PREDICATES ) {
ClosableIterator i = graph.find( node, expressionPredicate.getNode(), null );
if( i.hasNext() ) {
monitor.incrementProgress();
Triple t = i.next();
i.close();
return t;
}
}
return null;
}
private ATermAppl parseDataRangeLegacy(Node s, Node definition) {
if( !definition.isURI() ) {
addUnsupportedFeature( "Invalid datatype definition, expected URI but found " + s );
return ATermUtils.BOTTOM_LIT;
}
ATermAppl baseDatatype = ATermUtils.makeTermAppl( definition.getURI() );
Property[] datatypeFacets = new Property[] { OWL2.minInclusive, OWL2.maxInclusive,
OWL2.minExclusive, OWL2.maxExclusive, OWL2.totalDigits, OWL2.fractionDigits,
OWL2.pattern };
List restrictions = new ArrayList();
for( Property datatypeFacet : datatypeFacets ) {
Node facetValue = getObject( s, datatypeFacet.asNode() );
if( facetValue != null ) {
ATermAppl restriction = ATermUtils.makeFacetRestriction( ATermUtils
.makeTermAppl( datatypeFacet.getURI() ), JenaUtils.makeATerm( facetValue ) );
restrictions.add( restriction );
}
}
if( restrictions.isEmpty() ) {
addUnsupportedFeature( "A data range is defined without XSD facet restrictions "
+ s );
return ATermUtils.BOTTOM_LIT;
}
else {
return ATermUtils.makeRestrictedDatatype( baseDatatype, restrictions
.toArray( new ATermAppl[restrictions.size()] ) );
}
}
private ATermAppl parseDataRange(Node s, Node definition) {
if( !definition.isURI() ) {
addUnsupportedFeature( "Invalid datatype definition, expected URI but found " + s );
return ATermUtils.BOTTOM_LIT;
}
ATermAppl baseDatatype = ATermUtils.makeTermAppl( definition.getURI() );
Property[] datatypeFacets = new Property[] {
OWL2.minInclusive, OWL2.maxInclusive, OWL2.minExclusive, OWL2.maxExclusive,
OWL2.totalDigits, OWL2.fractionDigits, OWL2.pattern };
List restrictions = new ArrayList();
Node restrictionList = getObject( s, OWL2.withRestrictions.asNode() );
RDFListIterator i = new RDFListIterator( restrictionList );
while( i.hasNext() ) {
Node restrictionNode = i.next();
if( restrictionNode != null ) {
for( Property datatypeFacet : datatypeFacets ) {
Node facetValue = getObject( restrictionNode, datatypeFacet.asNode() );
if( facetValue != null ) {
ATermAppl restriction = ATermUtils.makeFacetRestriction( ATermUtils
.makeTermAppl( datatypeFacet.getURI() ), JenaUtils
.makeATerm( facetValue ) );
restrictions.add( restriction );
}
}
}
}
if( restrictions.isEmpty() ) {
addUnsupportedFeature( "A data range is defined without XSD facet restrictions "
+ s );
return ATermUtils.BOTTOM_LIT;
}
else {
return ATermUtils.makeRestrictedDatatype( baseDatatype, restrictions
.toArray( new ATermAppl[restrictions.size()] ) );
}
}
private void defineRule(Node node) {
List head = parseAtomList( getObject( node, SWRL.head.asNode() ) );
List body = parseAtomList( getObject( node, SWRL.body.asNode() ) );
if( head == null || body == null ) {
String whichPart = "head and body";
if( head != null ) {
whichPart = "body";
}
else if( body != null ) {
whichPart = "head";
}
addUnsupportedFeature( "Ignoring SWRL rule (unsupported " + whichPart + "): " + node );
return;
}
ATermAppl name = JenaUtils.makeATerm( node );
Rule rule = new Rule( name, head, body );
kb.addRule( rule );
}
private AtomDObject createRuleDObject(Node node) {
if( !node.isLiteral() ) {
ATermAppl name = node2term( node );
if( !ATermUtils.isPrimitive( name ) ) {
addUnsupportedFeature( "Cannot create rule data variable out of " + node );
return null;
}
return new AtomDVariable( name.toString() );
}
else {
return new AtomDConstant( node2term( node ) );
}
}
private AtomIObject createRuleIObject(Node node) {
if( hasObject( node, RDF.type.asNode(), SWRL.Variable.asNode() ) ) {
return new AtomIVariable( node.getURI() );
}
else {
ATermAppl term = node2term( node );
if( defineIndividual( term ) ) {
return new AtomIConstant( node2term( node ) );
}
else {
addUnsupportedFeature( "Cannot create rule individual object for node " + node );
return null;
}
}
}
private List parseAtomList(Node atomList) {
Node obj = null;
List atoms = new ArrayList();
while( atomList != null && !atomList.equals( RDF.nil.asNode() ) ) {
String atomType = "unsupported atom";
Node atomNode = getObject( atomList, RDF.first.asNode() );
RuleAtom atom = null;
if( hasObject( atomNode, RDF.type.asNode(), SWRL.ClassAtom.asNode() ) ) {
ATermAppl description = null;
AtomIObject argument = null;
atomType = "ClassAtom";
if( (obj = getObject( atomNode, SWRL.classPredicate.asNode() )) != null ) {
description = node2term( obj );
}
if( (obj = getObject( atomNode, SWRL.argument1.asNode() )) != null ) {
argument = createRuleIObject( obj );
}
if( description == null ) {
addUnsupportedFeature( "Error on " + SWRL.classPredicate );
}
else if( argument == null ) {
addUnsupportedFeature( "Error on" + SWRL.argument1 );
}
else {
atom = new ClassAtom( description, argument );
}
}
else if( hasObject( atomNode, RDF.type.asNode(), SWRL.IndividualPropertyAtom.asNode() ) ) {
ATermAppl pred = null;
AtomIObject argument1 = null;
AtomIObject argument2 = null;
atomType = "IndividualPropertyAtom";
if( (obj = getObject( atomNode, SWRL.propertyPredicate.asNode() )) != null ) {
pred = node2term( obj );
}
if( (obj = getObject( atomNode, SWRL.argument1.asNode() )) != null ) {
argument1 = createRuleIObject( obj );
}
if( (obj = getObject( atomNode, SWRL.argument2.asNode() )) != null ) {
argument2 = createRuleIObject( obj );
}
if( pred == null || !defineObjectProperty( pred ) ) {
addUnsupportedFeature( "Cannot define datatype property " + pred );
}
else if( argument1 == null ) {
addUnsupportedFeature( "Term not found: " + SWRL.argument1 );
}
else if( argument2 == null ) {
addUnsupportedFeature( "Term not found " + SWRL.argument2 );
}
else {
atom = new IndividualPropertyAtom( pred, argument1, argument2 );
}
}
else if( hasObject( atomNode, RDF.type.asNode(), SWRL.DifferentIndividualsAtom.asNode() ) ) {
AtomIObject argument1 = null;
AtomIObject argument2 = null;
atomType = "DifferentIndividualsAtom";
if( (obj = getObject( atomNode, SWRL.argument1.asNode() )) != null ) {
argument1 = createRuleIObject( obj );
}
if( (obj = getObject( atomNode, SWRL.argument2.asNode() )) != null ) {
argument2 = createRuleIObject( obj );
}
if( argument1 == null ) {
addUnsupportedFeature( "Term not found " + SWRL.argument1 );
}
else if( argument2 == null ) {
addUnsupportedFeature( "Term not found " + SWRL.argument2 );
}
else {
atom = new DifferentIndividualsAtom( argument1, argument2 );
}
}
else if( hasObject( atomNode, RDF.type.asNode(), SWRL.SameIndividualAtom.asNode() ) ) {
AtomIObject argument1 = null;
AtomIObject argument2 = null;
atomType = "SameIndividualAtom";
if( (obj = getObject( atomNode, SWRL.argument1.asNode() )) != null ) {
argument1 = createRuleIObject( obj );
}
if( (obj = getObject( atomNode, SWRL.argument2.asNode() )) != null ) {
argument2 = createRuleIObject( obj );
}
if( argument1 == null ) {
addUnsupportedFeature( "Term not found " + SWRL.argument1 );
}
else if( argument2 == null ) {
addUnsupportedFeature( "Term not found " + SWRL.argument2 );
}
else {
atom = new SameIndividualAtom( argument1, argument2 );
}
}
else if( hasObject( atomNode, RDF.type.asNode(), SWRL.DatavaluedPropertyAtom.asNode() ) ) {
ATermAppl pred = null;
AtomIObject argument1 = null;
AtomDObject argument2 = null;
atomType = "DatavaluedPropertyAtom";
if( (obj = getObject( atomNode, SWRL.propertyPredicate.asNode() )) != null ) {
pred = node2term( obj );
}
if( (obj = getObject( atomNode, SWRL.argument1.asNode() )) != null ) {
argument1 = createRuleIObject( obj );
}
if( (obj = getObject( atomNode, SWRL.argument2.asNode() )) != null ) {
argument2 = createRuleDObject( obj );
}
if( pred == null || !defineDatatypeProperty( pred ) ) {
addUnsupportedFeature( "Cannot define datatype property " + pred );
}
else if( argument1 == null ) {
addUnsupportedFeature( "Term not found " + SWRL.argument1 );
}
else if( argument2 == null ) {
addUnsupportedFeature( "Term not found " + SWRL.argument2 );
}
else {
atom = new DatavaluedPropertyAtom( pred, argument1, argument2 );
}
}
else if( hasObject( atomNode, RDF.type.asNode(), SWRL.BuiltinAtom.asNode() ) ) {
atomType = "BuiltinAtom";
Node builtInNode = null;
List arguments = null;
if( (obj = getObject( atomNode, SWRL.arguments.asNode() )) != null ) {
arguments = parseArgumentList( obj );
}
builtInNode = getObject( atomNode, SWRL.builtin.asNode() );
if( arguments == null ) {
addUnsupportedFeature( "Term not found " + SWRL.arguments );
}
else if( builtInNode != null && builtInNode.isURI() ) {
atom = new BuiltInAtom( builtInNode.getURI(), arguments );
}
}
else if( hasObject( atomNode, RDF.type.asNode(), SWRL.DataRangeAtom.asNode() ) ) {
atomType = "DataRangeAtom";
ATermAppl datatype = null;
AtomDObject argument = null;
if( (obj = getObject( atomNode, SWRL.dataRange.asNode() )) != null ) {
datatype = node2term( obj );
}
if( (obj = getObject( atomNode, SWRL.argument1.asNode() )) != null ) {
argument = createRuleDObject( obj );
}
if( datatype == null ) {
addUnsupportedFeature( "Term not found " + SWRL.dataRange );
}
else if( argument == null ) {
addUnsupportedFeature( "Term not found " + SWRL.argument1 );
}
else {
atom = new DataRangeAtom( datatype, argument );
}
}
if( atom == null ) {
addUnsupportedFeature( "Ignoring SWRL " + atomType + ": " + atomNode );
return null;
}
atoms.add( atom );
atomList = getObject( atomList, RDF.rest.asNode() );
}
if( atomList == null ) {
addUnsupportedFeature( "Not nil-terminated list in atom list! (Seen " + atoms + " )" );
return null;
}
return atoms;
}
private List parseArgumentList(Node argumentList) {
List arguments = new ArrayList();
while( argumentList != null && !argumentList.equals( RDF.nil.asNode() ) ) {
Node argumentNode = getObject( argumentList, RDF.first.asNode() );
if( argumentNode == null ) {
addUnsupportedFeature( "Term in list not found " + RDF.first );
}
else {
arguments.add( createRuleDObject( argumentNode ) );
argumentList = getObject( argumentList, RDF.rest.asNode() );
}
}
return arguments;
}
private boolean addNegatedAssertion(Node stmt) {
Node s = getObject( stmt, OWL2.sourceIndividual.asNode() );
if( s == null ) {
addUnsupportedFeature( "Negated property value is missing owl:sourceIndividual value" );
return false;
}
Node p = getObject( stmt, OWL2.assertionProperty.asNode() );
if( p == null ) {
addUnsupportedFeature( "Negated property value is missing owl:assertionProperty value" );
return false;
}
Node oi = getObject( stmt, OWL2.targetIndividual.asNode() );
Node ov = getObject( stmt, OWL2.targetValue.asNode() );
if( oi == null && ov == null ) {
addUnsupportedFeature( "Negated property value is missing owl:targetIndividual or owl:targetValue value" );
return false;
}
if( oi != null && ov != null ) {
addUnsupportedFeature( "Negated property value must not have owl:targetIndividual and owl:targetValue value" );
return false;
}
ATermAppl st = node2term( s );
ATermAppl pt = node2term( p );
ATermAppl ot;
defineIndividual( st );
if( oi != null ) {
ot = node2term( oi );
if( oi.isURI() || oi.isBlank() ) {
defineObjectProperty( pt );
defineIndividual( ot );
}
else {
addUnsupportedFeature( "Invalid negated property target individual " + stmt );
return false;
}
}
else {
ot = node2term( ov );
if( ov.isLiteral() ) {
defineDatatypeProperty( pt );
}
else {
addUnsupportedFeature( "Invalid negated property target value " + stmt );
return false;
}
}
if( !kb.addNegatedPropertyValue( pt, st, ot ) ) {
addUnsupportedFeature( "Skipping invalid negated property value " + stmt );
return false;
}
return true;
}
protected boolean defineClass(ATermAppl c) {
if( ATermUtils.isPrimitive( c ) ) {
kb.addClass( c );
return true;
}
else {
return ATermUtils.isComplexClass( c );
}
}
protected boolean defineDatatype(ATermAppl dt) {
if( ATermUtils.isPrimitive( dt ) ) {
kb.addDatatype( dt );
return true;
}
else {
return kb.isDatatype( dt );
}
}
/**
* There are two properties that are used in a subPropertyOf or
* equivalentProperty axiom. If one of them is defined as an Object (or
* Data) Property the other should also be defined as an Object (or Data)
* Property
*
* @param p1
* @param p2
* @return
*/
private boolean defineProperties(ATermAppl p1, ATermAppl p2) {
PropertyType type1 = kb.getPropertyType( p1 );
PropertyType type2 = kb.getPropertyType( p2 );
if( type1 != type2 ) {
if( type1 == PropertyType.UNTYPED ) {
if( type2 == PropertyType.OBJECT ) {
defineObjectProperty( p1 );
}
else if( type2 == PropertyType.DATATYPE ) {
defineDatatypeProperty( p1 );
}
}
else if( type2 == PropertyType.UNTYPED ) {
if( type1 == PropertyType.OBJECT ) {
defineObjectProperty( p2 );
}
else if( type1 == PropertyType.DATATYPE ) {
defineDatatypeProperty( p2 );
}
}
else {
// addWarning("Properties " + p1 + ", " + p2
// + " are related but first is " + PropertyType.TYPES[type1]
// + "Property and second is " + PropertyType.TYPES[type2]);
return false;
}
}
else if( type1 == PropertyType.UNTYPED ) {
defineProperty( p1 );
defineProperty( p2 );
}
return true;
}
protected boolean defineObjectProperty(ATermAppl c) {
if( !ATermUtils.isPrimitive( c ) && !ATermUtils.isInv( c ) ) {
return false;
}
return kb.addObjectProperty( c );
}
protected boolean defineDatatypeProperty(ATermAppl c) {
if( !ATermUtils.isPrimitive( c ) ) {
return false;
}
return kb.addDatatypeProperty( c );
}
private boolean defineAnnotationProperty(ATermAppl c) {
if( !ATermUtils.isPrimitive( c ) ) {
return false;
}
return kb.addAnnotationProperty( c );
}
protected boolean defineProperty(ATermAppl c) {
if( ATermUtils.isInv( c ) ) {
kb.addObjectProperty( c.getArgument( 0 ) );
return true;
}
else if( !ATermUtils.isPrimitive( c ) ) {
return false;
}
kb.addProperty( c );
return true;
}
protected boolean defineIndividual(ATermAppl c) {
kb.addIndividual( c );
return true;
}
@SuppressWarnings("unused")
private PropertyType guessPropertyType(ATermAppl p, Node prop) {
PropertyType roleType = kb.getPropertyType( p );
if( roleType != PropertyType.UNTYPED ) {
return roleType;
}
defineProperty( p );
Iterator> i = graph.find( prop, RDF.type.asNode(), null );
while( i.hasNext() ) {
Triple stmt = (Triple) i.next();
Node o = stmt.getObject();
if( o.equals( OWL.ObjectProperty.asNode() ) ) {
return PropertyType.OBJECT;
}
else if( o.equals( OWL.DatatypeProperty.asNode() ) ) {
return PropertyType.DATATYPE;
}
else if( o.equals( OWL.AnnotationProperty.asNode() ) ) {
return PropertyType.ANNOTATION;
}
else if( o.equals( OWL.OntologyProperty.asNode() ) ) {
return PropertyType.ANNOTATION;
}
}
return PropertyType.UNTYPED;
}
/**
* Process all triples with rdf:type
predicate. If
* {@link PelletOptions#PREPROCESS_TYPE_TRIPLES} option is true
* this function is a noop.
*/
protected void processTypes() {
if( preprocessTypeTriples ) {
log.fine( "processTypes" );
if( isLoadABox() ) {
processTypes( Node.ANY );
}
else {
for( Node type : TBOX_TYPES ) {
processTypes( type );
}
}
}
}
/**
* Process triples with rdf:type
predicate and given object.
* Type can be {@link Node.ANY} to indicate all type triples should be
* processed.
*
* @param type
* the object of rdf:type
triples to be processed
*/
protected void processTypes(Node type) {
ClosableIterator i = graph.find( null, RDF.type.asNode(), type );
while( i.hasNext() ) {
Triple stmt = i.next();
processType( stmt );
}
i.close();
}
/**
* Process a single rdf:type
triple. Type triples that are part
* of the OWL syntax, e.g. _:x rdf:type owl:Restriction
will
* not be processed since they are handled by the {@link #node2term(Node)}
* function.
*
* @param triple
* Type triple that will be processed
*/
protected void processType(Triple triple) {
Node s = triple.getSubject();
Node o = triple.getObject();
BuiltinTerm builtinTerm = BuiltinTerm.find( o );
if( builtinTerm != null ) {
if( builtinTerm.isSyntax() ) {
return;
}
// If we have a triple _:x rdf:type owl:Class then this is a noop
// that would only cache class expression for _:x. However, since
// we did not complete process all type triples unqualified cardinality
// restrictions would cause issues here since they require property
// to be either data or object property. Therefore, we stop processing
// this triple immediately before calling node2term function.
if( s.isBlank() && builtinTerm.equals( BuiltinTerm.OWL_Class ) ) {
return;
}
}
monitor.incrementProgress();
ATermAppl st = node2term( s );
if( builtinTerm == null ) {
if( PelletOptions.FREEZE_BUILTIN_NAMESPACES && o.isURI() ) {
String nameSpace = o.getNameSpace();
if( nameSpace != null ) {
BuiltinNamespace builtin = BuiltinNamespace.find( nameSpace );
if( builtin != null ) {
addUnsupportedFeature( "Ignoring triple with unknown term from " + builtin
+ " namespace: " + triple );
return;
}
}
}
return;
}
switch ( builtinTerm ) {
case RDF_Property:
defineProperty( st );
break;
case RDFS_Class:
defineClass( st );
break;
case RDFS_Datatype:
case OWL_DataRange:
if( s.isURI() ) {
defineDatatype( st );
}
else {
anonDatatypes.add( s );
}
break;
case OWL_Class:
defineClass( st );
break;
case OWL_Thing:
case OWL2_NamedIndividual:
defineIndividual( st );
break;
case OWL_Nothing:
defineIndividual( st );
kb.addType( st, ATermUtils.BOTTOM );
break;
case OWL_ObjectProperty:
if( s.isURI() && !defineObjectProperty( st ) ) {
addUnsupportedFeature( "Property " + st
+ " is defined both as an ObjectProperty and a "
+ kb.getPropertyType( st ) + "Property" );
}
break;
case OWL_DatatypeProperty:
if( !defineDatatypeProperty( st ) ) {
addUnsupportedFeature( "Property " + st
+ " is defined both as a DatatypeProperty and a "
+ kb.getPropertyType( st ) + "Property" );
}
break;
case OWL_FunctionalProperty:
defineProperty( st );
kb.addFunctionalProperty( st );
addSimpleProperty( st, CARDINALITY );
break;
case OWL_InverseFunctionalProperty:
if( defineProperty( st ) ) {
kb.addInverseFunctionalProperty( st );
addSimpleProperty( st, CARDINALITY );
}
else {
addUnsupportedFeature( "Ignoring InverseFunctionalProperty axiom for " + st + " ("
+ kb.getPropertyType( st ) + "Property)" );
}
break;
case OWL_TransitiveProperty:
if( defineObjectProperty( st ) ) {
kb.addTransitiveProperty( st );
}
else {
addUnsupportedFeature( "Ignoring TransitiveProperty axiom for " + st + " ("
+ kb.getPropertyType( st ) + "Property)" );
}
break;
case OWL_SymmetricProperty:
if( defineObjectProperty( st ) ) {
kb.addSymmetricProperty( st );
}
else {
addUnsupportedFeature( "Ignoring SymmetricProperty axiom for " + st + " ("
+ kb.getPropertyType( st ) + "Property)" );
}
break;
case OWL_AnnotationProperty:
if( !defineAnnotationProperty( st ) ) {
addUnsupportedFeature( "Property " + st
+ " is defined both as an AnnotationProperty and a "
+ kb.getPropertyType( st ) + "Property" );
}
break;
case OWL2_ReflexiveProperty:
if( defineObjectProperty( st ) ) {
kb.addReflexiveProperty( st );
}
else {
addUnsupportedFeature( "Ignoring ReflexiveProperty axiom for " + st + " ("
+ kb.getPropertyType( st ) + "Property)" );
}
break;
case OWL2_IrreflexiveProperty:
if( defineObjectProperty( st ) ) {
kb.addIrreflexiveProperty( st );
addSimpleProperty( st, IRREFLEXIVE );
}
else {
addUnsupportedFeature( "Ignoring IrreflexiveProperty axiom for " + st + " ("
+ kb.getPropertyType( st ) + "Property)" );
}
break;
case OWL2_AsymmetricProperty:
if( defineObjectProperty( st ) ) {
kb.addAsymmetricProperty( st );
addSimpleProperty( st, ANTI_SYM );
}
else {
addUnsupportedFeature( "Ignoring AntisymmetricProperty axiom for " + st + " ("
+ kb.getPropertyType( st ) + "Property)" );
}
break;
case OWL2_NegativePropertyAssertion:
addNegatedAssertion( s );
break;
case SWRL_Imp:
if( PelletOptions.DL_SAFE_RULES ) {
defineRule( s );
}
break;
case OWL_AllDifferent:
case OWL2_AllDisjointClasses:
case OWL2_AllDisjointProperties:
naryDisjoints.put( s, builtinTerm );
break;
default:
throw new InternalReasonerException( "Unexpected term: " + o );
}
}
/**
* Process all the triples in the raw graph. If
* {@link PelletOptions#PREPROCESS_TYPE_TRIPLES} option is true
* all rdf:type
will be ignored since they have already been
* processed with {@link #processTypes()} function.
*/
protected void processTriples() {
log.fine( "processTriples" );
if( isLoadABox() ) {
processTriples( Node.ANY );
}
else {
for( Node predicate : TBOX_PREDICATES ) {
processTriples( predicate );
}
}
}
/**
* Process triples with the given predicate. Predicate can be
* {@link Node.ANY} to indicate all triples should be processed.
*
* @param predicate
* Predicate of the triples that will be processed
*/
protected void processTriples(Node predicate) {
ClosableIterator i = graph.find( null, predicate, null );
while( i.hasNext() ) {
Triple triple = i.next();
processTriple( triple );
}
i.close();
}
/**
* Process a single triple that corresponds to an axiom (or a fact). This
* means triples that are part of OWL syntax, e.g. a triple with
* owl:onProperty
predicate, will not be processed since they
* are handled by the {@link #node2term(Node)} function. Also, if
* {@link PelletOptions#PREPROCESS_TYPE_TRIPLES} option is true
* any triple with rdf:type
predicate will be ignored.
*
* @param triple
* Triple to be processed.
*/
protected void processTriple(Triple triple) {
Node p = triple.getPredicate();
Node s = triple.getSubject();
Node o = triple.getObject();
BuiltinTerm builtinTerm = BuiltinTerm.find( p );
if( builtinTerm != null ) {
if( builtinTerm.isSyntax() ) {
return;
}
if( builtinTerm.equals( BuiltinTerm.RDF_type ) ) {
if( BuiltinTerm.find( o ) == null ) {
if( isLoadABox() ) {
ATermAppl ot = node2term( o );
if (!AnnotationClasses.contains(ot)) {
defineClass( ot );
ATermAppl st = node2term( s );
defineIndividual( st );
kb.addType( st, ot );
}
}
}
else if( !preprocessTypeTriples ) {
processType( triple );
}
return;
}
}
monitor.incrementProgress();
ATermAppl st = node2term( s );
ATermAppl ot = node2term( o );
if( builtinTerm == null ) {
ATermAppl pt = node2term( p );
Role role = kb.getProperty( pt );
PropertyType type = (role == null)
? PropertyType.UNTYPED
: role.getType();
if( type == PropertyType.ANNOTATION ) {
// Skip ontology annotations
if( graph.contains( s, RDF.type.asNode(), OWL.Ontology.asNode() ) ) {
return;
}
if( defineAnnotationProperty( pt ) ) {
kb.addAnnotation( st, pt, ot );
}
return;
}
if( PelletOptions.FREEZE_BUILTIN_NAMESPACES ) {
String nameSpace = p.getNameSpace();
if( nameSpace != null ) {
BuiltinNamespace builtin = BuiltinNamespace.find( nameSpace );
if( builtin != null ) {
addUnsupportedFeature( "Ignoring triple with unknown property from "
+ builtin + " namespace: " + triple );
return;
}
}
}
if( o.isLiteral() ) {
if( defineDatatypeProperty( pt ) ) {
String datatypeURI = ((ATermAppl) ot.getArgument( 2 )).getName();
if( defineIndividual( st ) ) {
defineDatatypeProperty( pt );
if( !datatypeURI.equals( "" ) ) {
defineDatatype( ATermUtils.makeTermAppl( datatypeURI ) );
}
kb.addPropertyValue( pt, st, ot );
}
else if( type == PropertyType.UNTYPED ) {
defineAnnotationProperty( pt );
}
else {
addUnsupportedFeature( "Ignoring ObjectProperty used with a class expression: "
+ triple );
}
}
else {
addUnsupportedFeature( "Ignoring literal value used with ObjectProperty : "
+ triple );
}
}
else {
if( !defineObjectProperty( pt ) ) {
addUnsupportedFeature( "Ignoring object value used with DatatypeProperty: "
+ triple );
}
else if( !defineIndividual( st ) ) {
addUnsupportedFeature( "Ignoring class expression used in subject position: "
+ triple );
}
else if( !defineIndividual( ot ) ) {
addUnsupportedFeature( "Ignoring class expression used in object position: "
+ triple );
}
else {
kb.addPropertyValue( pt, st, ot );
}
}
return;
}
switch ( builtinTerm ) {
case RDFS_subClassOf:
if( !defineClass( st ) ) {
addUnsupportedFeature( "Ignoring subClassOf axiom because the subject is not a class "
+ st + " rdfs:subClassOf " + ot );
}
else if( !defineClass( ot ) ) {
addUnsupportedFeature( "Ignoring subClassOf axiom because the object is not a class "
+ st + " rdfs:subClassOf " + ot );
}
else {
kb.addSubClass( st, ot );
}
break;
case RDFS_subPropertyOf:
ATerm subProp = null;
if( s.isBlank() ) {
Triple expr = getExpression( s );
if( expr == null ) {
addUnsupportedFeature( "Bnode in rdfs:subProperty axioms is not a valid property expression" );
}
else if( expr.getPredicate().equals( OWL2.inverseOf.asNode() ) ) {
if( defineObjectProperty( (ATermAppl) st.getArgument( 0 ) )
&& defineObjectProperty( ot ) ) {
subProp = st;
}
}
else if( expr.getPredicate().equals( OWL2.propertyChain.asNode() ) ) {
subProp = createList( expr.getObject() );
ATermList list = (ATermList) subProp;
while( !list.isEmpty() ) {
if( !defineObjectProperty( (ATermAppl) list.getFirst() ) ) {
break;
}
list = list.getNext();
}
if( !list.isEmpty() || !defineObjectProperty( ot ) ) {
subProp = null;
}
}
else {
addUnsupportedFeature( "Bnode in rdfs:subProperty axioms is not a valid property expression" );
}
}
else if( defineProperties( st, ot ) ) {
subProp = st;
}
if( subProp != null ) {
kb.addSubProperty( subProp, ot );
}
else {
addUnsupportedFeature( "Ignoring subproperty axiom between " + st + " ("
+ kb.getPropertyType( st ) + "Property) and " + ot + " ("
+ kb.getPropertyType( ot ) + "Property)" );
}
break;
case RDFS_domain:
if( kb.isAnnotationProperty( st ) ) {
addUnsupportedFeature( "Ignoring domain axiom for AnnotationProperty " + st );
}
else {
defineProperty( st );
defineClass( ot );
kb.addDomain( st, ot );
}
break;
case RDFS_range:
if( kb.isAnnotationProperty( st ) ) {
addUnsupportedFeature( "Ignoring range axiom for AnnotationProperty " + st );
break;
}
if( kb.isDatatype( ot ) ) {
defineDatatypeProperty( st );
}
else if( kb.isClass( ot ) ) {
defineObjectProperty( st );
}
else {
defineProperty( st );
}
if( kb.isDatatypeProperty( st ) ) {
defineDatatype( ot );
}
else if( kb.isObjectProperty( st ) ) {
defineClass( ot );
}
kb.addRange( st, ot );
break;
case OWL_intersectionOf:
ATermList list = createList( o );
defineClass( st );
ATermAppl conjunction = ATermUtils.makeAnd( list );
kb.addEquivalentClass( st, conjunction );
break;
case OWL_unionOf:
list = createList( o );
defineClass( st );
ATermAppl disjunction = ATermUtils.makeOr( list );
kb.addEquivalentClass( st, disjunction );
break;
case OWL2_disjointUnionOf:
list = createList( o );
kb.addDisjointClasses( list );
defineClass( st );
disjunction = ATermUtils.makeOr( list );
kb.addEquivalentClass( st, disjunction );
break;
case OWL_complementOf:
if( !defineClass( st ) ) {
addUnsupportedFeature( "Ignoring complementOf axiom because the subject is not a class "
+ st + " owl:complementOf " + ot );
}
else if( !defineClass( ot ) ) {
addUnsupportedFeature( "Ignoring complementOf axiom because the object is not a class "
+ st + " owl:complementOf " + ot );
}
else {
kb.addComplementClass( st, ot );
}
break;
case OWL_equivalentClass:
if( kb.isDatatype( ot ) || anonDatatypes.contains( o ) ) {
if( !defineDatatype( st ) ) {
addUnsupportedFeature( "Ignoring equivalentClass axiom because the subject is not a datatype "
+ st + " owl:equivalentClass " + ot );
}
else {
kb.addDatatypeDefinition( st, ot );
}
}
else if( !defineClass( st ) ) {
addUnsupportedFeature( "Ignoring equivalentClass axiom because the subject is not a class "
+ st + " owl:equivalentClass " + ot );
}
else if( !defineClass( ot ) ) {
addUnsupportedFeature( "Ignoring equivalentClass axiom because the object is not a class "
+ st + " owl:equivalentClass " + ot );
}
else {
kb.addEquivalentClass( st, ot );
}
break;
case OWL_disjointWith:
if( !defineClass( st ) ) {
addUnsupportedFeature( "Ignoring disjointWith axiom because the subject is not a class "
+ st + " owl:disjointWith " + ot );
}
else if( !defineClass( ot ) ) {
addUnsupportedFeature( "Ignoring disjointWith axiom because the object is not a class "
+ st + " owl:disjointWith " + ot );
}
else {
kb.addDisjointClass( st, ot );
}
break;
case OWL2_propertyDisjointWith:
if( defineProperties( st, ot ) ) {
kb.addDisjointProperty( st, ot );
addSimpleProperty( st, DISJOINT );
addSimpleProperty( ot, DISJOINT );
}
else {
addUnsupportedFeature( "Ignoring disjoint property axiom between " + st + " ("
+ kb.getPropertyType( st ) + "Property) and " + ot + " ("
+ kb.getPropertyType( ot ) + "Property)" );
}
break;
case OWL2_propertyChainAxiom:
ATermAppl superProp = null;
if( s.isBlank() ) {
Triple expr = getExpression( s );
if( expr == null ) {
addUnsupportedFeature( "Bnode in owl:propertyChainAxiom axiom is not a valid property expression" );
}
else if( expr.getPredicate().equals( OWL2.inverseOf.asNode() ) ) {
if( defineObjectProperty( (ATermAppl) st.getArgument( 0 ) ) ) {
superProp = st;
}
}
else {
addUnsupportedFeature( "Bnode in owl:propertyChainAxiom axiom is not a valid property expression" );
}
}
else if( defineObjectProperty( st ) ) {
superProp = st;
}
subProp = createList( o );
list = (ATermList) subProp;
while( !list.isEmpty() ) {
if( !defineObjectProperty( (ATermAppl) list.getFirst() ) ) {
break;
}
list = list.getNext();
}
if( !list.isEmpty() ) {
subProp = null;
}
if( subProp != null && superProp != null ) {
kb.addSubProperty( subProp, superProp );
}
else {
addUnsupportedFeature( "Ignoring property chain axiom between " + st + " ("
+ kb.getPropertyType( st ) + "Property) and " + ot );
}
break;
case OWL_equivalentProperty:
if( defineProperties( st, ot ) ) {
kb.addEquivalentProperty( st, ot );
}
else {
addUnsupportedFeature( "Ignoring equivalent property axiom between " + st + " ("
+ kb.getPropertyType( st ) + "Property) and " + ot + " ("
+ kb.getPropertyType( ot ) + "Property)" );
}
break;
case OWL_inverseOf:
if( defineObjectProperty( st ) && defineObjectProperty( ot ) ) {
kb.addInverseProperty( st, ot );
}
else {
addUnsupportedFeature( "Ignoring inverseOf axiom between " + st + " ("
+ kb.getPropertyType( st ) + "Property) and " + ot + " ("
+ kb.getPropertyType( ot ) + "Property)" );
}
break;
case OWL_sameAs:
if( defineIndividual( st ) && defineIndividual( ot ) ) {
kb.addSame( st, ot );
}
else {
addUnsupportedFeature( "Ignoring sameAs axiom between " + st + " and " + ot );
}
break;
case OWL_differentFrom:
if( defineIndividual( st ) && defineIndividual( ot ) ) {
kb.addDifferent( st, ot );
}
else {
addUnsupportedFeature( "Ignoring differentFrom axiom between " + st + " and " + ot );
}
break;
case OWL_distinctMembers:
list = createList( o );
for( ATermList l = list; !l.isEmpty(); l = l.getNext() ) {
ATermAppl c = (ATermAppl) l.getFirst();
defineIndividual( c );
}
kb.addAllDifferent( list );
break;
case OWL_members:
BuiltinTerm entityType = null;
if( preprocessTypeTriples ) {
entityType = naryDisjoints.get( s );
}
else {
Node type = getObject( s, RDF.type.asNode() );
if( type != null ) {
entityType = BuiltinTerm.find( type );
}
}
if( entityType == null ) {
addUnsupportedFeature( "There is no valid rdf:type for an owl:members assertion: "
+ s );
}
else if( !OWL_MEMBERS_TYPES.contains( entityType ) ) {
addUnsupportedFeature( "The rdf:type for an owl:members assertion is not recognized: "
+ entityType );
}
else {
list = createList( o );
for( ATermList l = list; !l.isEmpty(); l = l.getNext() ) {
ATermAppl c = (ATermAppl) l.getFirst();
switch ( entityType ) {
case OWL_AllDifferent:
defineIndividual( c );
break;
case OWL2_AllDisjointClasses:
defineClass( c );
break;
case OWL2_AllDisjointProperties:
defineProperty( c );
break;
}
}
switch ( entityType ) {
case OWL_AllDifferent:
kb.addAllDifferent( list );
break;
case OWL2_AllDisjointClasses:
kb.addDisjointClasses( list );
break;
case OWL2_AllDisjointProperties:
kb.addDisjointProperties( list );
break;
}
}
break;
case OWL_oneOf:
ATermList resultList = ATermUtils.EMPTY_LIST;
if( kb.isDatatype( st ) ) {
return;
}
// assert the subject is a class
defineClass( st );
disjunction = null;
list = createList( o );
if( o.equals( RDF.nil.asNode() ) ) {
disjunction = ATermUtils.BOTTOM;
}
else {
for( ATermList l = list; !l.isEmpty(); l = l.getNext() ) {
ATermAppl c = (ATermAppl) l.getFirst();
if( PelletOptions.USE_PSEUDO_NOMINALS ) {
ATermAppl nominal = ATermUtils.makeTermAppl( c.getName() + "_nominal" );
resultList = resultList.insert( nominal );
defineClass( nominal );
defineIndividual( c );
kb.addType( c, nominal );
}
else {
defineIndividual( c );
resultList = resultList.insert( ATermUtils.makeValue( c ) );
}
}
disjunction = ATermUtils.makeOr( resultList );
}
kb.addEquivalentClass( st, disjunction );
break;
case OWL2_hasKey:
if( o.equals( RDF.nil.asNode() ) ) {
return;
}
Set properties = new HashSet();
// assert the subject is a class
defineClass( st );
list = createList( o );
for( ATermList l = list; !l.isEmpty(); l = l.getNext() ) {
ATermAppl f = (ATermAppl) l.getFirst();
defineProperty( f );
properties.add( f );
}
kb.addKey( st, properties );
break;
case OWL2_topDataProperty:
case OWL2_bottomDataProperty:
case OWL2_topObjectProperty:
case OWL2_bottomObjectProperty:
defineIndividual( st );
kb.addPropertyValue( node2term(p), st, ot );
break;
default:
throw new InternalReasonerException( "Unrecognized term: " + p );
}
}
protected void processUntypedResources() {
log.fine( "processUntypedResource" );
for( Role r : kb.getRBox().getRoles().toArray( new Role[0] ) ) {
SimpleProperty why = simpleProperties.get( r.getName() );
if( why != null ) {
String msg = null;
if( r.isTransitive() ) {
msg = "transitivity axiom";
}
else if( r.hasComplexSubRole() ) {
msg = "complex sub property axiom";
}
if( msg != null ) {
msg = "Ignoring " + msg + " due to an existing " + why + " for property " + r;
addUnsupportedFeature( msg );
r.removeSubRoleChains();
}
}
if( r.isUntypedRole() ) {
/*
* Untyped roles are made object properties unless they have
* datatype super or sub-roles
*/
boolean rangeToDatatype = false;
Set roles = SetUtils.union( r.getSubRoles(), r.getSuperRoles() );
for( Role sub: roles ) {
switch ( sub.getType() ) {
case OBJECT:
defineObjectProperty( r.getName() );
break;
case DATATYPE:
defineDatatypeProperty( r.getName() );
rangeToDatatype = true;
break;
default:
continue;
}
}
if (!rangeToDatatype) {
defineObjectProperty( r.getName() );
}
/*
* If a typing assumption has been made, carry over to any
* untyped range entity
*/
Set ranges = r.getRanges();
if( ranges != null ) {
if( rangeToDatatype ) {
for( ATermAppl range : ranges ) {
if( (range.getAFun().getArity() == 0) && (!kb.isDatatype( range )) ) {
defineDatatype( range );
}
}
}
else {
for( ATermAppl range : ranges ) {
if( (range.getAFun().getArity() == 0) && (!kb.isClass( range )) ) {
defineClass( range );
}
}
}
}
}
}
}
public void setKB(KnowledgeBase kb) {
this.kb = kb;
}
private void defineBuiltinProperties() {
defineAnnotationProperty( node2term( RDFS.label.asNode() ) );
defineAnnotationProperty( node2term( RDFS.comment.asNode() ) );
defineAnnotationProperty( node2term( RDFS.seeAlso.asNode() ) );
defineAnnotationProperty( node2term( RDFS.isDefinedBy.asNode() ) );
defineAnnotationProperty( node2term( OWL.versionInfo.asNode() ) );
defineAnnotationProperty( node2term( OWL.backwardCompatibleWith.asNode() ) );
defineAnnotationProperty( node2term( OWL.priorVersion.asNode() ) );
defineAnnotationProperty( node2term( OWL.incompatibleWith.asNode() ) );
}
/**
* {@inheritDoc}
*/
public void load(Iterable graphs) throws UnsupportedFeatureException {
Timer timer = kb.timers.startTimer( "load" );
monitor.setProgressTitle( "Loading" );
monitor.taskStarted();
graph = EMPTY_GRAPH;
preprocess();
for (Graph g : graphs) {
graph = g;
processTypes();
}
for (Graph g : graphs) {
graph = g;
processTriples();
}
processUntypedResources();
monitor.taskFinished();
timer.stop();
}
/**
* {@inheritDoc}
*/
public void preprocess() {
defineBuiltinProperties();
}
public boolean isLoadABox() {
return loadABox;
}
public void setLoadABox(boolean loadABox) {
this.loadABox = loadABox;
}
public boolean isPreprocessTypeTriples() {
return preprocessTypeTriples;
}
public void setPreprocessTypeTriples(boolean preprocessTypeTriples) {
this.preprocessTypeTriples = preprocessTypeTriples;
}
}