private static void simplify(Query query) {
domainRangeSimplification( query );
}
private static Query preprocess(final Query query) {
Query q = query;
Set<ATermAppl> undistVars = q.getUndistVars();
// SAMEAS
// replace of SameAs atoms that contain at least one undistinguished
// or non-result variable.
boolean boundSameAs = true;
while( boundSameAs ) {
boundSameAs = false;
for( final QueryAtom atom : q.findAtoms( QueryPredicate.SameAs, null, null ) ) {
final ATermAppl a1 = atom.getArguments().get( 0 );
final ATermAppl a2 = atom.getArguments().get( 1 );
boolean replaceA1 = false;
boolean replaceA2 = false;
if( !a1.equals( a2 ) ) {
if( undistVars.contains( a1 ) )
replaceA1 = true;
else if( undistVars.contains( a2 ) )
replaceA2 = true;
else if( ATermUtils.isVar( a1 ) && !q.getResultVars().contains( a1 ) )
replaceA1 = true;
else if( ATermUtils.isVar( a2 ) && !q.getResultVars().contains( a2 ) )
replaceA2 = true;
}
if( replaceA1 || replaceA2 ) {
final ResultBinding b;
if( replaceA1 ) {
b = new ResultBindingImpl();
b.setValue( a1, a2 );
}
else {
b = new ResultBindingImpl();
b.setValue( a2, a1 );
}
q = q.apply( b );
boundSameAs = true;
break;
}
}
}
// Remove sameAs statements where:
// 1) Both arguments are the same
// 2) Neither is a result variable
// 3) Removing the atom doesn't result in an empty query
for( final QueryAtom atom : q.findAtoms( QueryPredicate.SameAs, null, null ) ) {
final ATermAppl a1 = atom.getArguments().get( 0 );
final ATermAppl a2 = atom.getArguments().get( 1 );
// Could remove sameAs with result vars if we could guarantee the query still contained an
// atom containing the variable.
if( a1.equals( a2 ) && !q.getResultVars().contains( a1 ) && q.getAtoms().size() > 1 ) {
q.remove( atom );
}
}
// Undistinguished variables + CLASS and PROPERTY variables
// TODO bug : queries Type(_:x,?x) and PropertyValue(_:x, ?x, . ) and
// PropertyValue(., ?x, _:x) have to be enriched with one more atom
// evaluating class/property DVs.
for( final QueryAtom a : new HashSet<QueryAtom>( q.getAtoms() ) ) {
switch ( a.getPredicate() ) {
case Type:
case DirectType:
final ATermAppl clazz = a.getArguments().get( 1 );
if( undistVars.contains( clazz ) && undistVars.contains( a.getArguments().get( 0 ) ) ) {
q.add( QueryAtomFactory.SubClassOfAtom( clazz, clazz ) );
}
break;
case PropertyValue:
final ATermAppl property = a.getArguments().get( 1 );
if( undistVars.contains( a.getArguments().get( 0 ) )
|| undistVars.contains( a.getArguments().get( 2 ) )
&& q.getDistVars().contains( property ) ) {
q.add( QueryAtomFactory.SubPropertyOfAtom( property, property ) );
}
break;
default:
break;
}