}
protected void applySomeValuesRule( Individual x, ATermAppl sv ) {
// someValuesFrom is now in the form not(all(p. not(c)))
ATermAppl a = (ATermAppl) sv.getArgument( 0 );
ATermAppl s = (ATermAppl) a.getArgument( 0 );
ATermAppl c = (ATermAppl) a.getArgument( 1 );
DependencySet ds = x.getDepends( sv );
if(!PelletOptions.MAINTAIN_COMPLETION_QUEUE && ds == null)
return;
c = ATermUtils.negate( c );
// Special rule to optimize topObjectProperty
if ( s.equals( ATermUtils.TOP_OBJECT_PROPERTY ) ) {
if ( ATermUtils.isNominal( c ) )
return;
for ( Node node : strategy.getABox().getNodes() ) {
if ( node.isIndividual() && !node.isPruned() && node.hasType( c ) ) {
return;
}
}
Individual y = strategy.createFreshIndividual( x, ds );
strategy.addType( y, c, ds );
return;
}
Role role = strategy.getABox().getRole( s );
// Is there a r-neighbor that satisfies the someValuesFrom restriction
boolean neighborFound = false;
// Safety condition as defined in the SHOIQ algorithm.
// An R-neighbor y of a node x is safe if
// (i) x is blockable or if
// (ii) x is a nominal node and y is not blocked.
boolean neighborSafe = x.isBlockable();
// y is going to be the node we create, and edge its connection to the
// current node
Node y = null;
Edge edge = null;
// edges contains all the edges going into of coming out from the node
// And labeled with the role R
EdgeList edges = x.getRNeighborEdges( role );
// We examine all those edges one by one and check if the neighbor has
// type C, in which case we set neighborFound to true
for( Iterator<Edge> i = edges.iterator(); i.hasNext(); ) {
edge = i.next();
y = edge.getNeighbor( x );
if( PelletOptions.USE_COMPLETION_QUEUE && y.isPruned() ){
y = null;
continue;
}
if( y.hasType( c ) ) {
neighborFound = neighborSafe || y.isLiteral() || !strategy.getBlocking().isBlocked( (Individual) y );
if( neighborFound ) {
break;
}
}
}
// If we have found a R-neighbor with type C, continue, do nothing
if( neighborFound )
return;
// If not, we have to create it
// If the role is a datatype property...
if( role.isDatatypeRole() ) {
Literal literal = (Literal) y;
if( ATermUtils.isNominal( c ) && !PelletOptions.USE_PSEUDO_NOMINALS ) {
strategy.getABox().copyOnWrite();
final ATermAppl input = (ATermAppl) c.getArgument( 0 );
ATermAppl canonical;
if( input.getArgument( ATermUtils.LIT_URI_INDEX ).equals( ATermUtils.NO_DATATYPE ) ) {
canonical = input;
}
else {
try {
canonical = strategy.getABox().getDatatypeReasoner().getCanonicalRepresentation( input );
} catch( InvalidLiteralException e ) {
final String msg = "Invalid literal encountered in nominal when attempting to apply some values rule: "
+ e.getMessage();
throw new InternalReasonerException( msg, e );
} catch( UnrecognizedDatatypeException e ) {
final String msg = "Unrecognized datatype for literal encountered in nominal when attempting to apply some values rule: "
+ e.getMessage();
throw new InternalReasonerException( msg, e );
}
}
literal = strategy.getABox().addLiteral( canonical );
}
else {
if( !role.isFunctional() || literal == null ) {
literal = strategy.getABox().addLiteral( ds );
}
else {
ds = ds.union( role.getExplainFunctional(), strategy.getABox().doExplanation() );
ds = ds.union( edge.getDepends(), strategy.getABox().doExplanation() );
}
strategy.addType( literal, c, ds );
}
if( log.isLoggable( Level.FINE ) )
log.fine( "SOME: " + x + " -> " + s + " -> " + literal + " : " + ATermUtils.toString( c ) + " - " + ds );
strategy. addEdge( x, role, literal, ds );
}
// If it is an object property
else {
if( ATermUtils.isNominal( c ) && !PelletOptions.USE_PSEUDO_NOMINALS ) {
strategy.getABox().copyOnWrite();
ATermAppl value = (ATermAppl) c.getArgument( 0 );
y = strategy.getABox().getIndividual( value );
if( log.isLoggable( Level.FINE ) )
log.fine( "VAL : " + x + " -> " + ATermUtils.toString( s ) + " -> " + y + " - " + ds );