: kb.getClasses();
for( final ATermAppl ic : instanceCandidates ) {
if( direct
? kb.getInstances( ic, direct ).contains( ic )
: kb.isType( ic, ic ) ) {
final ResultBinding candidateBinding = binding.duplicate();
if( ATermUtils.isVar( tI ) ) {
candidateBinding.setValue( tI, ic );
}
exec( candidateBinding );
}
}
}
else {
final Set<ATermAppl> classCandidates;
if( !ATermUtils.isVar( tC ) ) {
classCandidates = Collections.singleton( tC );
instanceCandidates = kb.getInstances( tC, direct );
}
else if( !ATermUtils.isVar( tI ) ) {
// classCandidates = flatten(TaxonomyUtils.getTypes(kb
// .getTaxonomy(), tI, direct)); // TODO
classCandidates = flatten( kb.getTypes( tI, direct ) ); // TODO
instanceCandidates = Collections.singleton( tI );
}
else {
classCandidates = kb.getAllClasses();
}
// explore all possible bindings
boolean loadInstances = (instanceCandidates == null);
for( final ATermAppl cls : classCandidates ) {
if( loadInstances ) {
instanceCandidates = kb.getInstances( cls, direct );
}
for( final ATermAppl inst : instanceCandidates ) {
runNext( binding, arguments, inst, cls );
}
} // finish explore bindings
}
break;
case PropertyValue: // TODO implementation of downMonotonic vars
final ATermAppl pvI = arguments.get( 0 );
final ATermAppl pvP = arguments.get( 1 );
final ATermAppl pvIL = arguments.get( 2 );
Collection<ATermAppl> propertyCandidates = null;
Collection<ATermAppl> subjectCandidates = null;
Collection<ATermAppl> objectCandidates = null;
boolean loadProperty = false;
boolean loadSubjects = false;
boolean loadObjects = false;
if( !ATermUtils.isVar( pvP ) ) {
propertyCandidates = Collections.singleton( pvP );
if( !ATermUtils.isVar( pvI ) ) {
subjectCandidates = Collections.singleton( pvI );
objectCandidates = kb.getPropertyValues( pvP, pvI );
}
else if( !ATermUtils.isVar( pvIL ) ) {
objectCandidates = Collections.singleton( pvIL );
subjectCandidates = kb.getIndividualsWithProperty( pvP, pvIL );
}
loadProperty = false;
}
else {
if( !ATermUtils.isVar( pvI ) ) {
subjectCandidates = Collections.singleton( pvI );
}
if( !ATermUtils.isVar( pvIL ) ) {
objectCandidates = Collections.singleton( pvIL );
}
else if( !plan.getQuery().getDistVarsForType( VarType.LITERAL ).contains( pvIL ) ) {
propertyCandidates = kb.getObjectProperties();
}
if( propertyCandidates == null ) {
propertyCandidates = kb.getProperties();
}
loadProperty = true;
}
loadSubjects = (subjectCandidates == null);
loadObjects = (objectCandidates == null);
for( final ATermAppl property : propertyCandidates ) {
// TODO replace this nasty if-cascade with some map for
// var
// bindings.
if( loadObjects && loadSubjects ) {
if( pvI.equals( pvIL ) ) {
if( pvI.equals( pvP ) ) {
if( !kb.hasPropertyValue( property, property, property ) ) {
continue;
}
runNext( binding, arguments, property, property, property );
}
else {
for( final ATermAppl i : kb.getIndividuals() ) {
if( !kb.hasPropertyValue( i, property, i ) ) {
continue;
}
runNext( binding, arguments, i, property, i );
}
}
}
else {
if( pvI.equals( pvP ) ) {
for( final ATermAppl i : kb.getIndividuals() ) {
if( !kb.hasPropertyValue( property, property, i ) ) {
continue;
}
runNext( binding, arguments, property, property, i );
}
}
else if( pvIL.equals( pvP ) ) {
for( final ATermAppl i : kb.getIndividuals() ) {
if( !kb.hasPropertyValue( i, property, property ) ) {
continue;
}
runNext( binding, arguments, i, property, property );
}
}
else {
for( final ATermAppl subject : kb.getIndividuals() ) {
for( final ATermAppl object : kb.getPropertyValues( property,
subject ) ) {
runNext( binding, arguments, subject, property, object );
}
}
}
}
}
else if( loadObjects ) {
// subject is known.
if( pvP.equals( pvIL ) ) {
if( !kb.hasPropertyValue( subjectCandidates.iterator().next(),
property, property ) ) {
// terminate
subjectCandidates = Collections.emptySet();
}
}
for( final ATermAppl subject : subjectCandidates ) {
for( final ATermAppl object : kb.getPropertyValues( property, subject ) ) {
runNext( binding, arguments, subject, property, object );
}
}
}
else {
// object is known.
for( final ATermAppl object : objectCandidates ) {
if( loadSubjects ) {
if( pvI.equals( pvP ) ) {
if( kb.hasPropertyValue( property, property, object ) ) {
subjectCandidates = Collections.singleton( property );
}
else {
// terminate
subjectCandidates = Collections.emptySet();
}
}
else {
subjectCandidates = new HashSet<ATermAppl>( kb
.getIndividualsWithProperty( property, object ) );
}
}
for( final ATermAppl subject : subjectCandidates ) {
if( loadProperty
&& !kb.hasPropertyValue( subject, property, object ) ) {
continue;
}
runNext( binding, arguments, subject, property, object );
}
}
}
} // finish visiting non-ground triple.
break;
case SameAs:
// optimize - merge nodes
final ATermAppl saI1 = arguments.get( 0 );
final ATermAppl saI2 = arguments.get( 1 );
for( final ATermAppl known : getSymmetricCandidates( VarType.INDIVIDUAL, saI1, saI2 ) ) {
final Set<ATermAppl> dependents;
if( saI1.equals( saI2 ) ) {
dependents = Collections.singleton( known );
}
else {
dependents = kb.getAllSames( known );
}
for( final ATermAppl dependent : dependents ) {
runSymetricCheck( current, saI1, known, saI2, dependent, binding );
}
}
break;
case DifferentFrom:
// optimize - different from map
final ATermAppl dfI1 = arguments.get( 0 );
final ATermAppl dfI2 = arguments.get( 1 );
if( !dfI1.equals( dfI2 ) ) {
for( final ATermAppl known : getSymmetricCandidates( VarType.INDIVIDUAL, dfI1,
dfI2 ) ) {
for( final ATermAppl dependent : kb.getDifferents( known ) ) {
runSymetricCheck( current, dfI1, known, dfI2, dependent, binding );
}
}
}
else {
if( log.isLoggable( Level.FINER ) ) {
log.finer( "Atom " + current
+ "cannot be satisfied in any consistent ontology." );
}
}
// TODO What about undist vars ?
// Query : PropertyValue(?x,p,_:x), Type(_:x, C),
// DifferentFrom( _:x, x) .
// Data : p(a,x) . p(b,y) . C(x) . C(y) .
// Result: {b}
//
// Data : p(a,x) . (exists p (C and {y}))(b) . C(x) .
// Result: {y}
//
// rolling-up to ?x : (exists p (C and not {x}))(?x) .
//
// More complex problems :
// Query : PropertyValue(?x,p,_:x), Type(_:x, C),
// DifferentFrom( _:x, _:y) . Type(_:y, T) .
// Data : p(a,x) . C(x) .
// Result: {a}
//
// Query : PropertyValue(?x,p,_:x), Type(_:x, C),
// DifferentFrom( _:x, _:y) . Type(_:y, T) .
// Data : p(x,x) . C(x) .
// Result: {}
//
// Query : PropertyValue(?x,p,_:x), Type(_:x, C),
// DifferentFrom( _:x, _:y) . Type(_:y, D) .
// Data : p(a,x) . C(x) . D(a) .
// Result: {a}
//
// rolling-up to ?x : (exists p (C and (not D)))(?x) .
//
// rolling-up to _:x of DifferentFrom(_:x,_:y) :
// roll-up(_:x) and (not roll-up(_:y)).
// but it is not complete if the rolling-up to _:y is not
// complete, but just a preprocessing (for example _:y is in
// a cycle).
break;
case Annotation:
final ATermAppl aI = arguments.get( 0 );
final ATermAppl aP = arguments.get( 1 );
final ATermAppl aIL = arguments.get( 2 );
subjectCandidates = null;
objectCandidates = null;
propertyCandidates = null;
//if aI is a variable, get all the annotation subjects
if( ATermUtils.isVar( aI ) ) {
subjectCandidates = kb.getAnnotationSubjects();
}
//else, we only have one subject candidate
else {
subjectCandidates = Collections.singleton( aI );
}
//if aP is a variable, get all the annotation properties
if( ATermUtils.isVar( aP ) ) {
propertyCandidates = kb.getAnnotationProperties();
}
//else, we only have one property candidate
else {
propertyCandidates = Collections.singleton( aP );
}
//if aIL is a variable, get all the annotation objects for the subject and the property candidates
if( ATermUtils.isVar( aIL ) ) {
for( final ATermAppl subject : subjectCandidates ) {
for( final ATermAppl property : propertyCandidates ) {
for( final ATermAppl object : kb.getAnnotations( subject, property ) ) {
runNext( binding, arguments, subject, property, object );
}
}
}
}
//else, we only have one object candidate
else {
for( final ATermAppl subject : subjectCandidates ) {
for( final ATermAppl property : propertyCandidates ) {
if( kb.isAnnotation(subject, property, aIL) ) {
runNext( binding, arguments, subject, property, aIL );
}
}
}
}
break;
// throw new IllegalArgumentException("The annotation atom "
// + current + " should be ground, but is not.");
// TBOX ATOMS
case DirectSubClassOf:
direct = true;
case StrictSubClassOf:
strict = true;
case SubClassOf:
final ATermAppl scLHS = arguments.get( 0 );
final ATermAppl scRHS = arguments.get( 1 );
if( scLHS.equals( scRHS ) ) {
// TODO optimization for downMonotonic variables
for( final ATermAppl ic : kb.getClasses() ) {
runNext( binding, arguments, ic, ic );
}
}
else {
final boolean lhsDM = isDownMonotonic( scLHS );
final boolean rhsDM = isDownMonotonic( scRHS );
if( lhsDM || rhsDM ) {
downMonotonic( kb.getTaxonomy(), kb.getClasses(), lhsDM, scLHS, scRHS,
binding, direct, strict );
}
else {
final Set<ATermAppl> lhsCandidates;
Set<ATermAppl> rhsCandidates = null;
if( !ATermUtils.isVar( scLHS ) ) {
lhsCandidates = Collections.singleton( scLHS );
rhsCandidates = flatten( kb.getSuperClasses( scLHS, direct ) );
rhsCandidates.addAll( kb.getEquivalentClasses( scLHS ) );
if( strict ) {
rhsCandidates.removeAll( kb.getEquivalentClasses( scLHS ) );
}
else if( !ATermUtils.isComplexClass( scLHS ) ) {
rhsCandidates.add( scLHS );
}
}
else if( !ATermUtils.isVar( scRHS ) ) {
rhsCandidates = Collections.singleton( scRHS );
if( scRHS.equals( ATermUtils.TOP ) ) {
lhsCandidates = new HashSet<ATermAppl>( kb.getAllClasses() );
}
else {
lhsCandidates = flatten( kb.getSubClasses( scRHS, direct ) );
lhsCandidates.addAll( kb.getAllEquivalentClasses( scRHS ) );
}
if( strict ) {
lhsCandidates.removeAll( kb.getAllEquivalentClasses( scRHS ) );
}
}
else {
lhsCandidates = kb.getClasses();
}
boolean reload = (rhsCandidates == null);
for( final ATermAppl subject : lhsCandidates ) {
if( reload ) {
rhsCandidates = flatten( kb.getSuperClasses( subject, direct ) );
if( strict ) {
rhsCandidates.removeAll( kb.getEquivalentClasses( subject ) );
}
else if( !ATermUtils.isComplexClass( subject ) ) {
rhsCandidates.add( subject );
}
}
for( final ATermAppl object : rhsCandidates ) {
runNext( binding, arguments, subject, object );
}
}
}
}
break;
case EquivalentClass: // TODO implementation of downMonotonic vars
final ATermAppl eqcLHS = arguments.get( 0 );
final ATermAppl eqcRHS = arguments.get( 1 );
for( final ATermAppl known : getSymmetricCandidates( VarType.CLASS, eqcLHS, eqcRHS ) ) {
// TODO optimize - try just one - if success then take
// all
// found bindings and extend them for other equivalent
// classes as well.
// meanwhile just a simple check below
final Set<ATermAppl> dependents;
if( eqcLHS.equals( eqcRHS ) ) {
dependents = Collections.singleton( known );
}
else {
dependents = kb.getEquivalentClasses( known );
}
for( final ATermAppl dependent : dependents ) {
int size = result.size();
runSymetricCheck( current, eqcLHS, known, eqcRHS, dependent, binding );
if( result.size() == size ) {
// no binding found, so that there is no need to
// explore other equivalent classes - they fail
// as
// well.
break;
}
}
}
break;
case DisjointWith: // TODO implementation of downMonotonic vars
final ATermAppl dwLHS = arguments.get( 0 );
final ATermAppl dwRHS = arguments.get( 1 );
if( !dwLHS.equals( dwRHS ) ) {
// TODO optimizeTBox
for( final ATermAppl known : getSymmetricCandidates( VarType.CLASS, dwLHS,
dwRHS ) ) {
for( final Set<ATermAppl> dependents : kb.getDisjointClasses( known ) ) {
for( final ATermAppl dependent : dependents ) {
runSymetricCheck( current, dwLHS, known, dwRHS, dependent, binding );
}
}
}
}
else {
log.finer( "Atom " + current
+ "cannot be satisfied in any consistent ontology." );
}
break;
case ComplementOf: // TODO implementation of downMonotonic vars
final ATermAppl coLHS = arguments.get( 0 );
final ATermAppl coRHS = arguments.get( 1 );
if( !coLHS.equals( coRHS ) ) {
// TODO optimizeTBox
for( final ATermAppl known : getSymmetricCandidates( VarType.CLASS, coLHS,
coRHS ) ) {
for( final ATermAppl dependent : kb.getComplements( known ) ) {
runSymetricCheck( current, coLHS, known, coRHS, dependent, binding );
}
}
}
else {
log.finer( "Atom " + current
+ "cannot be satisfied in any consistent ontology." );
}
break;
// RBOX ATOMS
case DirectSubPropertyOf:
direct = true;
case StrictSubPropertyOf:
strict = true;
case SubPropertyOf:
final ATermAppl spLHS = arguments.get( 0 );
final ATermAppl spRHS = arguments.get( 1 );
if( spLHS.equals( spRHS ) ) {
// TODO optimization for downMonotonic variables
for( final ATermAppl ic : kb.getProperties() ) {
runNext( binding, arguments, ic, ic );
}
}
else {
final boolean lhsDM = isDownMonotonic( spLHS );
final boolean rhsDM = isDownMonotonic( spRHS );
if( lhsDM || rhsDM ) {
downMonotonic( kb.getRoleTaxonomy(true), kb.getProperties(), lhsDM, spLHS,
spRHS, binding, direct, strict );
}
else {
final Set<ATermAppl> spLhsCandidates;
Set<ATermAppl> spRhsCandidates = null;
if( !ATermUtils.isVar( spLHS ) ) {
spLhsCandidates = Collections.singleton( spLHS );
spRhsCandidates = flatten( kb.getSuperProperties( spLHS, direct ) );
if( strict ) {
spRhsCandidates.removeAll( kb.getEquivalentProperties( spLHS ) );
}
else {
spRhsCandidates.add( spLHS );
}
}
else if( !ATermUtils.isVar( spRHS ) ) {
spRhsCandidates = Collections.singleton( spRHS );
spLhsCandidates = flatten( kb.getSubProperties( spRHS, direct ) );
if( strict ) {
spLhsCandidates.removeAll( kb.getEquivalentProperties( spRHS ) );
}
else {
spLhsCandidates.add( spRHS );
}
}
else {
spLhsCandidates = kb.getProperties();
}
boolean reload = (spRhsCandidates == null);
for( final ATermAppl subject : spLhsCandidates ) {
if( reload ) {
spRhsCandidates = flatten( kb.getSuperProperties( subject, direct ) );
if( strict ) {
spRhsCandidates
.removeAll( kb.getEquivalentProperties( subject ) );
}
else {
spRhsCandidates.add( subject );
}
}
for( final ATermAppl object : spRhsCandidates ) {
runNext( binding, arguments, subject, object );
}
}
}
}
break;
case EquivalentProperty: // TODO implementation of downMonotonic
// vars
final ATermAppl eqpLHS = arguments.get( 0 );
final ATermAppl eqpRHS = arguments.get( 1 );
// TODO optimize - try just one - if success then take all
// found
// bindings and extend them for other equivalent classes as
// well.
// meanwhile just a simple check below
for( final ATermAppl known : getSymmetricCandidates( VarType.PROPERTY, eqpLHS,
eqpRHS ) ) {
final Set<ATermAppl> dependents;
if( eqpLHS.equals( eqpRHS ) ) {
dependents = Collections.singleton( known );
}
else {
dependents = kb.getEquivalentProperties( known );
}
for( final ATermAppl dependent : dependents ) {
int size = result.size();
runSymetricCheck( current, eqpLHS, known, eqpRHS, dependent, binding );
if( result.size() == size ) {
// no binding found, so that there is no need to
// explore other equivalent classes - they fail
// as
// well.
break;
}
}
}
break;
case Domain:
final ATermAppl domLHS = arguments.get( 0 );
final ATermAppl domRHS = arguments.get( 1 );
Collection<ATermAppl> domLhsCandidates;
Collection<ATermAppl> domRhsCandidates;
if ( !ATermUtils.isVar( domLHS ) ) {
domLhsCandidates = Collections.singleton( domLHS );
} else {
domLhsCandidates = kb.getProperties();
}
if ( !ATermUtils.isVar( domRHS ) ) {
domRhsCandidates = Collections.singleton( domRHS );
} else {
domRhsCandidates = kb.getAllClasses();
}
for ( ATermAppl prop : domLhsCandidates) {
for ( ATermAppl cls : domRhsCandidates ) {
//System.out.println("Checking dom(" + prop + ", " + cls + ")");
if ( (kb.isDatatypeProperty( prop ) || kb.isObjectProperty( prop ))
&& kb.hasDomain( prop, cls ) ) {
runNext( binding, arguments, prop, cls );
}
}
}
break;
case Range:
final ATermAppl rangeLHS = arguments.get( 0 );
final ATermAppl rangeRHS = arguments.get( 1 );
Collection<ATermAppl> rangeLhsCandidates;
Collection<ATermAppl> rangeRhsClassCandidates;
Collection<ATermAppl> rangeRhsDTypeCandidates;
if ( !ATermUtils.isVar( rangeLHS ) ) {
rangeLhsCandidates = Collections.singleton( rangeLHS );
} else {
rangeLhsCandidates = kb.getProperties();
}
if ( !ATermUtils.isVar( rangeRHS ) ) {
//System.out.println( "Bound range: " + rangeRHS );
if ( kb.isDatatype( rangeRHS ) ) {
rangeRhsClassCandidates = Collections.emptySet();
rangeRhsDTypeCandidates = Collections.singleton( rangeRHS );
} else {
rangeRhsClassCandidates = Collections.singleton( rangeRHS );
rangeRhsDTypeCandidates = Collections.emptySet();
}
} else {
rangeRhsClassCandidates = kb.getAllClasses();
// TODO : change the datatype reasoner to keep track of associated aterms.
rangeRhsDTypeCandidates = new HashSet<ATermAppl>();
for (ATermAppl dtype : kb.getDatatypeReasoner().listDataRanges() ) {
rangeRhsDTypeCandidates.add( dtype );
}
}
for ( ATermAppl prop : rangeLhsCandidates) {
if( kb.isObjectProperty( prop ) ) {
for( ATermAppl cls : rangeRhsClassCandidates ) {
//System.out.println("Checking range(" + prop + ", " + cls + ")");
if( kb.hasRange( prop, cls ) ) {
runNext( binding, arguments, prop, cls );
}
}
}
else if ( kb.isDatatypeProperty( prop ) ) {
for( ATermAppl dtype : rangeRhsDTypeCandidates ) {
//System.out.println("Checking range(" + prop + ", " + dtype + ")");
if ( kb.hasRange( prop, dtype ) ) {
runNext( binding, arguments, prop, dtype );
}
}
}
}
break;
case InverseOf: // TODO implementation of downMonotonic vars
final ATermAppl ioLHS = arguments.get( 0 );
final ATermAppl ioRHS = arguments.get( 1 );
if( ioLHS.equals( ioRHS ) ) {
runAllPropertyChecks( current, arguments.get( 0 ), kb.getSymmetricProperties(),
binding );
}
else {
for( final ATermAppl known : getSymmetricCandidates( VarType.PROPERTY, ioLHS,
ioRHS ) ) {
// meanwhile workaround
for( final ATermAppl dependent : kb.getInverses( known ) ) {
runSymetricCheck( current, ioLHS, known, ioRHS, dependent, binding );
}
}
}
break;
case Symmetric:
runAllPropertyChecks( current, arguments.get( 0 ), kb.getSymmetricProperties(),
binding );
break;
case Asymmetric:
runAllPropertyChecks( current, arguments.get( 0 ), kb.getAsymmetricProperties(),
binding );
break;
case Reflexive:
runAllPropertyChecks( current, arguments.get( 0 ), kb.getReflexiveProperties(),
binding );
break;
case Irreflexive:
runAllPropertyChecks( current, arguments.get( 0 ), kb.getIrreflexiveProperties(),
binding );
break;
case ObjectProperty:
runAllPropertyChecks( current, arguments.get( 0 ), kb.getObjectProperties(),
binding );
break;
case DatatypeProperty:
runAllPropertyChecks( current, arguments.get( 0 ), kb.getDataProperties(), binding );
break;
case Functional:
runAllPropertyChecks( current, arguments.get( 0 ), kb.getFunctionalProperties(),
binding );
break;
case InverseFunctional:
runAllPropertyChecks( current, arguments.get( 0 ), kb
.getInverseFunctionalProperties(), binding );
break;
case Transitive:
runAllPropertyChecks( current, arguments.get( 0 ), kb.getTransitiveProperties(),
binding );
break;
case UndistVarCore:
// TODO Core IF
final CoreNewImpl core = (CoreNewImpl) current.apply( binding );
final Collection<ATermAppl> distVars = core.getDistVars();
if( distVars.isEmpty() ) {
final Collection<ATermAppl> constants = core.getConstants();
if( constants.isEmpty() ) {
if( QueryEngine.execBooleanABoxQuery( core.getQuery() ) ) {
result.add( binding );
// throw new RuntimeException(
// "The query contains neither dist vars, nor constants,
// yet evaluated by the CombinedQueryEngine !!! ");
}
}
else {
final ATermAppl c = constants.iterator().next();
final ATermAppl clazz = core.getQuery().rollUpTo( c,
Collections.<ATermAppl>emptySet(), STOP_ROLLING_ON_CONSTANTS );
if( kb.isType( c, clazz ) ) {
exec( binding );
}
}
}
else if( distVars.size() == 1 ) {
final ATermAppl var = distVars.iterator().next();
final ATermAppl c = core.getQuery().rollUpTo( var, Collections.<ATermAppl>emptySet(),
STOP_ROLLING_ON_CONSTANTS );
final Collection<ATermAppl> instances = kb.getInstances( c );
for( final ATermAppl a : instances ) {
final ResultBinding candidateBinding = binding.duplicate();
candidateBinding.setValue( var, a );
exec( candidateBinding );
}
}
else {
// TODO