Set<Role> functionalSupers = s.getFunctionalSupers();
if( functionalSupers.isEmpty() )
functionalSupers = SetUtils.singleton( s );
LOOP:
for( Iterator<Role> it = functionalSupers.iterator(); it.hasNext(); ) {
Role r = it.next();
if (PelletOptions.USE_TRACING) {
ds = ds.union( s.getExplainSuper(r.getName()), strategy.getABox().doExplanation() ).union( r.getExplainFunctional(), strategy.getABox().doExplanation() );
}
EdgeList edges = x.getRNeighborEdges( r );
// if there is not more than one edge then func max rule won't be triggered
if( edges.size() <= 1 )
continue;
// find all distinct R-neighbors of x
Set<Node> neighbors = edges.getFilteredNeighbors( x, c );
// if there is not more than one neighbor then func max rule won't be triggered
if( neighbors.size() <= 1 )
continue;
Node head = null;
int edgeIndex = 0;
int edgeCount = edges.size();
// find the head and its corresponding dependency information.
// since head is not necessarily the first element in the
// neighbor list we need to first find the un-pruned node
for( ; edgeIndex < edgeCount; edgeIndex++ ) {
Edge edge = edges.edgeAt( edgeIndex );
head = edge.getNeighbor( x );
if( head.isPruned() || !neighbors.contains( head ) )
continue;
// this node is included in the merge list because the edge
// exists and the node has the qualification in its types
ds = ds.union( edge.getDepends(), strategy.getABox().doExplanation() );
ds = ds.union( head.getDepends( c ), strategy.getABox().doExplanation() );
ds = ds.union( r.getExplainSubOrInv( edge.getRole() ), strategy.getABox().doExplanation() );
break;
}
// now iterate through the rest of the elements in the neighbors
// and merge them to the head node. it is possible that we will
// switch the head at some point because of merging rules such
// that you always merge to a nominal of higher level
for( edgeIndex++; edgeIndex < edgeCount; edgeIndex++ ) {
Edge edge = edges.edgeAt( edgeIndex );
Node next = edge.getNeighbor( x );
if( next.isPruned() || !neighbors.contains( next ) )
continue;
// it is possible that there are multiple edges to the same
// node, e.g. property p and its super property, so check if
// we already merged this one
if( head.isSame( next ) )
continue;
// this node is included in the merge list because the edge
// exists and the node has the qualification in its types
ds = ds.union( edge.getDepends(), strategy.getABox().doExplanation() );
ds = ds.union( next.getDepends( c ), strategy.getABox().doExplanation() );
ds = ds.union( r.getExplainSubOrInv( edge.getRole() ), strategy.getABox().doExplanation() );
if( next.isDifferent( head ) ) {
ds = ds.union( head.getDepends( c ), strategy.getABox().doExplanation() );
ds = ds.union( next.getDepends( c ), strategy.getABox().doExplanation() );
ds = ds.union( next.getDifferenceDependency( head ), strategy.getABox().doExplanation() );
if( r.isFunctional() )
strategy.getABox().setClash( Clash.functionalCardinality( x, ds, r.getName() ) );
else
strategy.getABox().setClash( Clash.maxCardinality( x, ds, r.getName(), 1 ) );
break;
}
if( x.isNominal() && head.isBlockable() && next.isBlockable()