Package com.clarkparsia.pellet.sparqldl.engine

Source Code of com.clarkparsia.pellet.sparqldl.engine.QueryCost

// Copyright (c) 2006 - 2008, Clark & Parsia, LLC. <http://www.clarkparsia.com>
// This source code is 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: licensing@clarkparsia.com

package com.clarkparsia.pellet.sparqldl.engine;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.mindswap.pellet.KnowledgeBase;
import org.mindswap.pellet.exceptions.UnsupportedFeatureException;
import org.mindswap.pellet.utils.ATermUtils;
import org.mindswap.pellet.utils.KBOperation;
import org.mindswap.pellet.utils.SizeEstimate;

import aterm.ATermAppl;

import com.clarkparsia.pellet.sparqldl.model.Core;
import com.clarkparsia.pellet.sparqldl.model.NotKnownQueryAtom;
import com.clarkparsia.pellet.sparqldl.model.QueryAtom;
import com.clarkparsia.pellet.sparqldl.model.UnionQueryAtom;

/**
* <p>
* Title: AtomCostImpl
* </p>
* <p>
* Description: Computes the cost estimate for given atom.
* </p>
* <p>
* Copyright: Copyright (c) 2007
* </p>
* <p>
* Company: Clark & Parsia, LLC. <http://www.clarkparsia.com>
* </p>
*
* @author Petr Kremen
*/
public class QueryCost {
  private double      staticCost;

  private double      branchCount;
 
  private KnowledgeBase  kb;

  private SizeEstimate  estimate;

  public QueryCost(KnowledgeBase kb) {
    this.kb = kb;
    this.estimate = kb.getSizeEstimate();
  }


  public double estimate(List<QueryAtom> atoms) {
    return estimate( atoms, new HashSet<ATermAppl>() );
  }

  public double estimate(List<QueryAtom> atoms, Collection<ATermAppl> bound) {
    double totalStaticCount = 1.0;
    double totalBranchCount = 1.0;

    branchCount = 1;
    staticCost = 1.0;

    int n = atoms.size();
   
    Set<ATermAppl> lastBound = new HashSet<ATermAppl>( bound );
    List<Set<ATermAppl>> boundList = new ArrayList<Set<ATermAppl>>(n);
    for( int i = 0; i < n; i++ ) {
      QueryAtom atom = atoms.get( i );
     
      boundList.add( lastBound );
     
      lastBound = new HashSet<ATermAppl>( lastBound );
      lastBound.addAll( atom.getArguments() )
    }
   
   
    for( int i = n - 1; i >= 0; i-- ) {
      QueryAtom atom = atoms.get( i );

      estimate( atom, boundList.get( i ) );

      totalBranchCount *= branchCount;
      totalStaticCount = staticCost + branchCount * totalStaticCount;
    }

    staticCost = totalStaticCount;
    branchCount = totalBranchCount;
   
    return staticCost;
  }
 
  public double estimate(final QueryAtom atom) {
    return estimate( atom, new HashSet<ATermAppl>() );
  }
 
  public double estimate(final QueryAtom atom, final Collection<ATermAppl> bound) {
    boolean direct = false;
    boolean strict = false;

    List<ATermAppl> arguments = atom.getArguments();
    for( ATermAppl a : arguments ) {
      if( isConstant( a ) ) {
        bound.add( a );
      }
    }

    switch ( atom.getPredicate() ) {
    case DirectType:
      direct = true;
    case Type:
      ATermAppl instance = arguments.get( 0 );
      ATermAppl clazz = arguments.get( 1 );

      if( bound.containsAll( arguments ) ) {
        staticCost = direct
          ? estimate.getCost( KBOperation.IS_DIRECT_TYPE )
          : estimate.getCost( KBOperation.IS_TYPE );
        branchCount = 1;
      }
      else if( bound.contains( clazz ) ) {
        staticCost = direct
          ? estimate.getCost( KBOperation.GET_DIRECT_INSTANCES )
          : estimate.getCost( KBOperation.GET_INSTANCES );
        branchCount = isConstant( clazz )
          ? estimate.size( clazz )
          : estimate.avgInstancesPerClass( direct );
      }
      else if( bound.contains( instance ) ) {
        staticCost = estimate.getCost( KBOperation.GET_TYPES );
        branchCount = isConstant( instance )
          ? estimate.classesPerInstance( instance, direct )
          : estimate.avgClassesPerInstance( direct );
      }
      else {
        staticCost = estimate.getClassCount() * (direct
          ? estimate.getCost( KBOperation.GET_DIRECT_INSTANCES )
          : estimate.getCost( KBOperation.GET_INSTANCES ));
        branchCount = estimate.getClassCount() * estimate.avgInstancesPerClass( direct );
      }
      break;

    case Annotation: // TODO
    case PropertyValue:
      if( bound.containsAll( arguments ) ) {
        staticCost = estimate.getCost( KBOperation.HAS_PROPERTY_VALUE );
        branchCount = 1;
      }
      else {
        ATermAppl subject = arguments.get( 0 );
        ATermAppl predicate = arguments.get( 1 );
        ATermAppl object = arguments.get( 2 );

        if( bound.contains( predicate ) ) {
          if( bound.contains( subject ) ) {
            staticCost = estimate.getCost( KBOperation.GET_PROPERTY_VALUE );
            branchCount = isConstant( predicate )
              ? estimate.avg( predicate )
              : estimate.avgSubjectsPerProperty();
          }
          else if( bound.contains( object ) ) {
            staticCost = estimate.getCost( KBOperation.GET_PROPERTY_VALUE );
            if( isConstant( predicate ) ) {
              if( kb.isObjectProperty( predicate ) ) {
                branchCount = estimate.avg( inv( predicate ) );
              }
              else {
                branchCount = estimate.avgSubjectsPerProperty();
              }
            }
            else {
              branchCount = estimate.avgSubjectsPerProperty();
            }
          }
          else {
            staticCost = estimate.getCost( KBOperation.GET_PROPERTY_VALUE )
            /*
             * TODO should be st. like
             * GET_INSTANCES_OF_ROLLED_CONCEPT that reflects the
             * complexity of the concept.
             */
            + (isConstant( predicate )
              ? estimate.avg( predicate )
              : estimate.avgSubjectsPerProperty())
                * estimate.getCost( KBOperation.GET_PROPERTY_VALUE );
            branchCount = (isConstant( predicate )
              ? estimate.size( predicate )
              : estimate.avgPairsPerProperty());
          }
        }
        else if( bound.contains( subject ) || bound.contains( object ) ) {
          staticCost = estimate.getPropertyCount()
              * estimate.getCost( KBOperation.GET_PROPERTY_VALUE );
          branchCount = estimate.getPropertyCount() * estimate.avgSubjectsPerProperty();
        }
        else {
          staticCost = estimate.getPropertyCount()
              * (estimate.getCost( KBOperation.GET_PROPERTY_VALUE )
              /*
               * TODO should be st. like
               * GET_INSTANCES_OF_ROLLED_CONCEPT that reflects the
               * complexity of the concept.
               */+ estimate.avgSubjectsPerProperty()
                  * estimate.getCost( KBOperation.GET_PROPERTY_VALUE ));
          branchCount = estimate.avgPairsPerProperty() * estimate.getPropertyCount();
        }
      }
      break;

    case SameAs:
      ATermAppl saLHS = arguments.get( 0 );
      ATermAppl saRHS = arguments.get( 1 );

      if( bound.containsAll( arguments ) ) {
        staticCost = estimate.getCost( KBOperation.IS_SAME_AS );
        branchCount = 1;
      }
      else if( bound.contains( saLHS ) || bound.contains( saRHS ) ) {
        staticCost = estimate.getCost( KBOperation.GET_SAMES );

        if( bound.contains( saLHS ) ) {
          branchCount = isConstant( saLHS )
            ? estimate.sames( saLHS )
            : estimate.avgSamesPerInstance();
        }
        else {
          branchCount = isConstant( saRHS )
            ? estimate.sames( saRHS )
            : estimate.avgSamesPerInstance();
        }
      }
      else {
        staticCost = estimate.getInstanceCount() * estimate.getCost( KBOperation.GET_SAMES );
        branchCount = estimate.getInstanceCount() * estimate.avgSamesPerInstance();
      }
      break;
    case DifferentFrom:
      ATermAppl dfLHS = arguments.get( 0 );
      ATermAppl dfRHS = arguments.get( 1 );

      if( bound.containsAll( arguments ) ) {
        staticCost = estimate.getCost( KBOperation.IS_DIFFERENT_FROM );
        branchCount = 1;
      }
      else if( bound.contains( dfLHS ) || bound.contains( dfRHS ) ) {
        staticCost = estimate.getCost( KBOperation.GET_DIFFERENTS );

        if( bound.contains( dfLHS ) ) {
          branchCount = isConstant( dfLHS )
            ? estimate.differents( dfLHS )
            : estimate.avgDifferentsPerInstance();
        }
        else {
          branchCount = isConstant( dfRHS )
            ? estimate.differents( dfRHS )
            : estimate.avgDifferentsPerInstance();
        }
      }
      else {
        staticCost = estimate.getInstanceCount()
            * estimate.getCost( KBOperation.GET_DIFFERENTS );
        branchCount = estimate.getInstanceCount() * estimate.avgDifferentsPerInstance();
      }
      break;

    case DirectSubClassOf:
      direct = true;
    case StrictSubClassOf:
      strict = true;
    case SubClassOf:
      ATermAppl clazzLHS = arguments.get( 0 );
      ATermAppl clazzRHS = arguments.get( 1 );

      if( bound.containsAll( arguments ) ) {
        if( strict ) {
          if( direct ) {
            staticCost = estimate.getCost( KBOperation.GET_DIRECT_SUB_OR_SUPERCLASSES );
          }
          else {
            staticCost = estimate.getCost( KBOperation.IS_SUBCLASS_OF )
                + estimate.getCost( KBOperation.GET_EQUIVALENT_CLASSES );
          }
        }
        else {
          staticCost = estimate.getCost( KBOperation.IS_SUBCLASS_OF );
        }

        branchCount = 1;
      }
      else if( bound.contains( clazzLHS ) || bound.contains( clazzRHS ) ) {
        if( strict && !direct ) {
          staticCost = estimate.getCost( KBOperation.GET_SUB_OR_SUPERCLASSES )
              + estimate.getCost( KBOperation.GET_EQUIVALENT_CLASSES );
        }
        else {
          staticCost = direct
            ? estimate.getCost( KBOperation.GET_DIRECT_SUB_OR_SUPERCLASSES )
            : estimate.getCost( KBOperation.GET_SUB_OR_SUPERCLASSES );
        }
        if( bound.contains( clazzLHS ) ) {
          branchCount = isConstant( clazzLHS )
            ? estimate.superClasses( clazzLHS, direct )
            : estimate.avgSuperClasses( direct );

          if( strict ) {
            branchCount -= isConstant( clazzLHS )
              ? estimate.equivClasses( clazzLHS )
              : estimate.avgEquivClasses();
            branchCount = Math.max( branchCount, 0 );
          }
        }
        else {
          branchCount = isConstant( clazzRHS )
            ? estimate.superClasses( clazzRHS, direct )
            : estimate.avgSuperClasses( direct );

          if( strict ) {
            branchCount -= isConstant( clazzRHS )
              ? estimate.equivClasses( clazzRHS )
              : estimate.avgEquivClasses();
            branchCount = Math.max( branchCount, 0 );
          }
        }
      }
      else {
        if( strict && !direct ) {
          staticCost = estimate.getCost( KBOperation.GET_SUB_OR_SUPERCLASSES )
              + estimate.getCost( KBOperation.GET_EQUIVALENT_CLASSES );
        }
        else {
          staticCost = direct
            ? estimate.getCost( KBOperation.GET_DIRECT_SUB_OR_SUPERCLASSES )
            : estimate.getCost( KBOperation.GET_SUB_OR_SUPERCLASSES );
        }

        staticCost *= estimate.getClassCount();

        branchCount = estimate.getClassCount() * estimate.avgSubClasses( direct );

        if( strict ) {
          branchCount -= estimate.avgEquivClasses();
          branchCount = Math.max( branchCount, 0 );
        }
      }
      break;
    case EquivalentClass:
      ATermAppl eqcLHS = arguments.get( 0 );
      ATermAppl eqcRHS = arguments.get( 1 );

      if( bound.containsAll( arguments ) ) {
        staticCost = estimate.getCost( KBOperation.IS_EQUIVALENT_CLASS );
        branchCount = 1;
      }
      else if( bound.contains( eqcLHS ) || bound.contains( eqcRHS ) ) {
        staticCost = estimate.getCost( KBOperation.GET_EQUIVALENT_CLASSES );

        if( bound.contains( eqcLHS ) ) {
          branchCount = isConstant( eqcLHS )
            ? estimate.equivClasses( eqcLHS )
            : estimate.avgEquivClasses();
        }
        else {
          branchCount = isConstant( eqcRHS )
            ? estimate.equivClasses( eqcRHS )
            : estimate.avgEquivClasses();
        }
      }
      else {
        staticCost = estimate.getClassCount()
            * estimate.getCost( KBOperation.GET_EQUIVALENT_CLASSES );
        branchCount = estimate.getClassCount() * estimate.avgEquivClasses();
      }
      break;
    case DisjointWith:
      ATermAppl dwLHS = arguments.get( 0 );
      ATermAppl dwRHS = arguments.get( 1 );

      if( bound.containsAll( arguments ) ) {
        staticCost = estimate.getCost( KBOperation.IS_DISJOINT_WITH );
        branchCount = 1;
      }
      else if( bound.contains( dwLHS ) || bound.contains( dwRHS ) ) {
        staticCost = estimate.getCost( KBOperation.GET_DISJOINT_CLASSES );

        if( bound.contains( dwLHS ) ) {
          branchCount = isConstant( dwLHS )
            ? estimate.disjoints( dwLHS )
            : estimate.avgDisjointClasses();
        }
        else {
          branchCount = isConstant( dwRHS )
            ? estimate.disjoints( dwRHS )
            : estimate.avgDisjointClasses();
        }
      }
      else {
        staticCost = estimate.getClassCount()
            * estimate.getCost( KBOperation.GET_DISJOINT_CLASSES );
        branchCount = estimate.getClassCount() * estimate.avgDisjointClasses();
      }
      break;
    case ComplementOf:
      ATermAppl coLHS = arguments.get( 0 );
      ATermAppl coRHS = arguments.get( 1 );

      if( bound.containsAll( arguments ) ) {
        staticCost = estimate.getCost( KBOperation.IS_COMPLEMENT_OF );
        branchCount = 1;
      }
      else if( bound.contains( coLHS ) || bound.contains( coRHS ) ) {
        staticCost = estimate.getCost( KBOperation.GET_COMPLEMENT_CLASSES );

        if( bound.contains( coLHS ) ) {
          branchCount = isConstant( coLHS )
            ? estimate.complements( coLHS )
            : estimate.avgComplementClasses();
        }
        else {
          branchCount = isConstant( coRHS )
            ? estimate.complements( coRHS )
            : estimate.avgComplementClasses();
        }
      }
      else {
        staticCost = estimate.getClassCount()
            * estimate.getCost( KBOperation.GET_COMPLEMENT_CLASSES );
        branchCount = estimate.getClassCount() * estimate.avgComplementClasses();
      }
      break;

    case DirectSubPropertyOf:
      direct = true;
    case StrictSubPropertyOf:
      strict = true;
    case SubPropertyOf:
      ATermAppl spLHS = arguments.get( 0 );
      ATermAppl spRHS = arguments.get( 1 );

      if( bound.containsAll( arguments ) ) {
        if( strict ) {
          if( direct ) {
            staticCost = estimate
                .getCost( KBOperation.GET_DIRECT_SUB_OR_SUPERPROPERTIES );
          }
          else {
            staticCost = estimate.getCost( KBOperation.IS_SUBPROPERTY_OF )
                + estimate.getCost( KBOperation.GET_EQUIVALENT_PROPERTIES );
          }
        }
        else {
          staticCost = estimate.getCost( KBOperation.IS_SUBPROPERTY_OF );
        }

        branchCount = 1;
      }
      else if( bound.contains( spLHS ) || bound.contains( spRHS ) ) {
        if( strict && !direct ) {
          staticCost = estimate.getCost( KBOperation.GET_SUB_OR_SUPERPROPERTIES )
              + estimate.getCost( KBOperation.GET_EQUIVALENT_PROPERTIES );
        }
        else {
          staticCost = direct
            ? estimate.getCost( KBOperation.GET_DIRECT_SUB_OR_SUPERPROPERTIES )
            : estimate.getCost( KBOperation.GET_SUB_OR_SUPERPROPERTIES );
        }
        if( bound.contains( spLHS ) ) {
          branchCount = isConstant( spLHS )
            ? estimate.superProperties( spLHS, direct )
            : estimate.avgSuperProperties( direct );

          if( strict ) {
            branchCount -= isConstant( spLHS )
              ? estimate.equivProperties( spLHS )
              : estimate.avgEquivProperties();
            branchCount = Math.max( branchCount, 0 );

          }
        }
        else {
          branchCount = isConstant( spRHS )
            ? estimate.superProperties( spRHS, direct )
            : estimate.avgSuperProperties( direct );

          if( strict ) {
            branchCount -= isConstant( spRHS )
              ? estimate.equivProperties( spRHS )
              : estimate.avgEquivProperties();
            branchCount = Math.max( branchCount, 0 );

          }
        }
      }
      else {
        if( strict && !direct ) {
          staticCost = estimate.getCost( KBOperation.GET_SUB_OR_SUPERPROPERTIES )
              + estimate.getCost( KBOperation.GET_EQUIVALENT_PROPERTIES );
        }
        else {
          staticCost = direct
            ? estimate.getCost( KBOperation.GET_DIRECT_SUB_OR_SUPERPROPERTIES )
            : estimate.getCost( KBOperation.GET_SUB_OR_SUPERPROPERTIES );
        }

        staticCost *= estimate.getPropertyCount();

        branchCount = estimate.getPropertyCount() * estimate.avgSubProperties( direct );

        if( strict ) {
          branchCount -= estimate.avgEquivProperties();
          branchCount = Math.max( branchCount, 0 );

        }
      }
      break;

    case EquivalentProperty:
      ATermAppl eqpLHS = arguments.get( 0 );
      ATermAppl eqpRHS = arguments.get( 1 );

      if( bound.containsAll( arguments ) ) {
        staticCost = estimate.getCost( KBOperation.IS_EQUIVALENT_PROPERTY );
        branchCount = 1;
      }
      else if( bound.contains( eqpLHS ) || bound.contains( eqpRHS ) ) {
        staticCost = estimate.getCost( KBOperation.GET_EQUIVALENT_PROPERTIES );

        if( bound.contains( eqpLHS ) ) {
          branchCount = isConstant( eqpLHS )
            ? estimate.equivProperties( eqpLHS )
            : estimate.avgEquivProperties();
        }
        else {
          branchCount = isConstant( eqpRHS )
            ? estimate.equivProperties( eqpRHS )
            : estimate.avgEquivProperties();
        }
      }
      else {
        staticCost = estimate.getPropertyCount()
            * estimate.getCost( KBOperation.GET_EQUIVALENT_PROPERTIES );
        branchCount = estimate.getPropertyCount() * estimate.avgEquivProperties();
      }
      break;
    case Domain:
      ATermAppl domLHS = arguments.get( 0 );
      ATermAppl domRHS = arguments.get( 1 );
     
      if( bound.containsAll( arguments ) ) {
        staticCost = estimate.getCost( KBOperation.IS_DOMAIN );
        branchCount = 1;
      }
      else if( bound.contains( domLHS ) || bound.contains( domRHS ) ) {
        staticCost = estimate.getCost( KBOperation.GET_DOMAINS );
       
        if( bound.contains( domLHS ) ) {
          branchCount = isConstant( domLHS )
            ? estimate.equivProperties( domLHS )
            : estimate.avgEquivProperties();
        }
        else {
          branchCount = isConstant( domRHS )
            ? estimate.equivClasses( domRHS )
            : estimate.avgEquivClasses();
        }
      }
      else {
        staticCost = estimate.getPropertyCount()
          * estimate.getCost( KBOperation.GET_DOMAINS );
        branchCount = estimate.getPropertyCount() * estimate.avgEquivProperties();
      }
      break;
    case Range:
      ATermAppl rangeLHS = arguments.get( 0 );
      ATermAppl rangeRHS = arguments.get( 1 );
     
      if( bound.containsAll( arguments ) ) {
        staticCost = estimate.getCost( KBOperation.IS_RANGE );
        branchCount = 1;
      }
      else if( bound.contains( rangeLHS ) || bound.contains( rangeRHS ) ) {
        staticCost = estimate.getCost( KBOperation.GET_RANGES );
       
        if( bound.contains( rangeLHS ) ) {
          branchCount = isConstant( rangeLHS )
            ? estimate.equivProperties( rangeLHS )
            : estimate.avgEquivProperties();
        }
        else {
          branchCount = isConstant( rangeRHS )
            ? estimate.equivClasses( rangeRHS )
            : estimate.avgEquivClasses();
        }
      }
      else {
        staticCost = estimate.getPropertyCount()
          * estimate.getCost( KBOperation.GET_RANGES );
        branchCount = estimate.getPropertyCount() * estimate.avgEquivProperties();
      }
     
      break;
    case InverseOf:
      ATermAppl ioLHS = arguments.get( 0 );
      ATermAppl ioRHS = arguments.get( 1 );

      if( bound.containsAll( arguments ) ) {
        staticCost = estimate.getCost( KBOperation.IS_INVERSE_OF );
        branchCount = 1;
      }
      else if( bound.contains( ioLHS ) || bound.contains( ioRHS ) ) {
        staticCost = estimate.getCost( KBOperation.GET_INVERSES );

        if( bound.contains( ioLHS ) ) {
          branchCount = isConstant( ioLHS )
            ? estimate.inverses( ioLHS )
            : estimate.avgInverseProperties();
        }
        else {
          branchCount = isConstant( ioRHS )
            ? estimate.inverses( ioRHS )
            : estimate.avgInverseProperties();
        }
      }
      else {
        staticCost = estimate.getPropertyCount()
            * estimate.getCost( KBOperation.GET_INVERSES );
        branchCount = estimate.getPropertyCount() * estimate.avgInverseProperties();
      }
      break;
    case ObjectProperty:
      if( bound.containsAll( arguments ) ) {
        staticCost = estimate.getCost( KBOperation.IS_OBJECT_PROPERTY );
        branchCount = 1;
      }
      else {
        staticCost = estimate.getCost( KBOperation.GET_OBJECT_PROPERTIES );
        branchCount = estimate.getObjectPropertyCount();
      }
      break;
    case DatatypeProperty:
      if( bound.containsAll( arguments ) ) {
        staticCost = estimate.getCost( KBOperation.IS_DATATYPE_PROPERTY );
        branchCount = 1;
      }
      else {
        staticCost = estimate.getCost( KBOperation.GET_DATATYPE_PROPERTIES );
        branchCount = estimate.getDataPropertyCount();
      }
      break;
    case Functional:
      if( bound.containsAll( arguments ) ) {
        staticCost = estimate.getCost( KBOperation.IS_FUNCTIONAL_PROPERTY );
        branchCount = 1;
      }
      else {
        staticCost = estimate.getCost( KBOperation.GET_FUNCTIONAL_PROPERTIES );
        branchCount = estimate.getFunctionalPropertyCount();
      }
      break;
    case InverseFunctional:
      if( bound.containsAll( arguments ) ) {
        staticCost = estimate.getCost( KBOperation.IS_INVERSE_FUNCTIONAL_PROPERTY );
        branchCount = 1;
      }
      else {
        staticCost = estimate.getCost( KBOperation.GET_INVERSE_FUNCTIONAL_PROPERTIES );
        branchCount = estimate.getInverseFunctionalPropertyCount();
      }
      break;
    case Transitive:
      if( bound.containsAll( arguments ) ) {
        staticCost = estimate.getCost( KBOperation.IS_TRANSITIVE_PROPERTY );
        branchCount = 1;
      }
      else {
        staticCost = estimate.getCost( KBOperation.GET_TRANSITIVE_PROPERTIES );
        branchCount = estimate.getTransitivePropertyCount();
      }
      break;
    case Symmetric:
      if( bound.containsAll( arguments ) ) {
        staticCost = estimate.getCost( KBOperation.IS_SYMMETRIC_PROPERTY );
        branchCount = 1;
      }
      else {
        staticCost = estimate.getCost( KBOperation.GET_SYMMETRIC_PROPERTIES );
        branchCount = estimate.getSymmetricPropertyCount();
      }
      break;
    case Asymmetric:
      if( bound.containsAll( arguments ) ) {
        staticCost = estimate.getCost( KBOperation.IS_ASYMMETRIC_PROPERTY );
        branchCount = 1;
      }
      else {
        staticCost = estimate.getCost( KBOperation.GET_ASYMMETRIC_PROPERTIES);
        branchCount = estimate.getSymmetricPropertyCount();
      }
      break;
    case Reflexive:
      if( bound.containsAll( arguments ) ) {
        staticCost = estimate.getCost( KBOperation.IS_REFLEXIVE_PROPERTY );
        branchCount = 1;
      }
      else {
        staticCost = estimate.getCost( KBOperation.GET_REFLEXIVE_PROPERTIES );
        branchCount = estimate.getSymmetricPropertyCount();
      }
      break;
    case Irreflexive:
      if( bound.containsAll( arguments ) ) {
        staticCost = estimate.getCost( KBOperation.IS_IRREFLEXIVE_PROPERTY );
        branchCount = 1;
      }
      else {
        staticCost = estimate.getCost( KBOperation.GET_IRREFLEXIVE_PROPERTIES );
        branchCount = estimate.getSymmetricPropertyCount();
      }
      break;
    case NotKnown:
      estimate( ((NotKnownQueryAtom) atom).getAtoms(), bound );
      break;
     
    case Union: {
      double totalStaticCount = 1.0;
      double totalBranchCount = 1.0;

      for( List<QueryAtom> atoms : ((UnionQueryAtom) atom).getUnion() ) {
        estimate( atoms, bound );

        totalBranchCount += branchCount;
        totalStaticCount += staticCost;
      }    

      staticCost = totalStaticCount;
      branchCount = totalBranchCount;
     
      break;
    }

    case UndistVarCore:
      // if (!bound.containsAll(query.getDistVarsForType(VarType.CLASS))
      // || !bound.containsAll(query
      // .getDistVarsForType(VarType.PROPERTY))) {
      // // meanwhile not supporting query orderings that allow evaluate
      // // schema atoms after a core.
      // return Double.MAX_VALUE;
      // }

      // neglecting rolling-ups
      if( bound.containsAll( arguments ) ) {
        staticCost = estimate.getCost( KBOperation.IS_TYPE );
        branchCount = 1;
      }
      else {
        Core core = (Core) atom;
        int n = core.getDistVars().size();

        double b = Math.pow( estimate.avgInstancesPerClass( false ), n );
        branchCount = b;

        switch ( QueryEngine.getStrategy( atom ) ) {
        case ALLFAST: // TODO
        case SIMPLE:
          staticCost = n * estimate.getCost( KBOperation.GET_INSTANCES ) + b
              * estimate.getCost( KBOperation.IS_TYPE );
          break;
        default:
          throw new IllegalArgumentException( "Not yet implemented." );
        }
      }
      break;
     
    case Datatype:
      if( bound.containsAll( arguments ) ) {
        staticCost = 1;
      }
      else {
        staticCost = Integer.MAX_VALUE;
      }
      branchCount = 1;
      break;
     
    default:
      throw new UnsupportedFeatureException( "Unknown atom type " + atom.getPredicate() + "." );
    }
   
    return staticCost;
  }

  /**
   * {@inheritDoc}
   */
  public double getBranchCount() {
    return branchCount;
  }

  /**
   * {@inheritDoc}
   */
  public double getStaticCost() {
    return staticCost;
  }

  private ATermAppl inv(ATermAppl pred) {
    return kb.getRBox().getRole( pred ).getInverse().getName();
  }

  private boolean isConstant(ATermAppl a) {
    return !ATermUtils.isVar( a );
  }

}
TOP

Related Classes of com.clarkparsia.pellet.sparqldl.engine.QueryCost

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.