Package com.clarkparsia.pellet.rules.builtins

Source Code of com.clarkparsia.pellet.rules.builtins.ComparisonTesters

// 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.rules.builtins;

import static java.lang.String.format;

import java.util.Arrays;
import java.util.Collections;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.mindswap.pellet.Literal;
import org.mindswap.pellet.utils.ATermUtils;

import aterm.ATermAppl;

import com.clarkparsia.pellet.datatypes.DatatypeReasoner;
import com.clarkparsia.pellet.datatypes.Facet;
import com.clarkparsia.pellet.datatypes.exceptions.DatatypeReasonerException;

/**
* <p>
* Title: Comparison Testers
* </p>
* <p>
* Description: Implementations for each of the SWRL comparison tests.
* </p>
* <p>
* Copyright: Copyright (c) 2007
* </p>
* <p>
* Company: Clark & Parsia, LLC. <http://www.clarkparsia.com>
* </p>
*
* @author Ron Alford
*/

public class ComparisonTesters {

  private static Logger  log;

  static {
    log = Logger.getLogger( ComparisonTesters.class.getCanonicalName() );
  }

  private static  class EqualityTester extends BinaryTester {
   
   
    private boolean flip;
   
    private EqualityTester( boolean flip ) {
      this.flip = flip;
    }
   
    protected boolean test( Literal a, Literal b) {
      Object aval = a.getValue();
      Object bval = b.getValue();
     
      // Numbers are a special case, since they can be promoted from Integers and Decimals to Floats and Doubles.
      if ( ( aval instanceof Number ) && ( bval instanceof Number ) ) {
        NumericPromotion promoter = new NumericPromotion();
        Number anum = (Number) aval;
        Number bnum = (Number) bval;
       
        promoter.promote( anum, bnum );
        NumericComparisonVisitor visitor = new NumericComparisonVisitor();
        promoter.accept( visitor );
       
        if ( visitor.getComparison() == 0 )
          return true ^ flip;
        return false ^ flip;
      }
     
      if ( a.getValue() != null && b.getValue() != null ) {
        return ( aval.getClass().equals( bval.getClass() ) && aval.equals( bval )) ^ flip;
      }
      return false;
    }
  }
 
  private static class OrderingTester extends BinaryTester {

    private boolean lt, inclusive;

    private OrderingTester(boolean flip, boolean inclusive) {
      this.lt = flip;
      this.inclusive = inclusive;
    }
   
    private boolean comparesWell( int comparison ) {
      if ( lt && comparison < 0 )
        return true;
      if ( !lt && comparison > 0 )
        return true;
      if ( inclusive && comparison == 0 )
        return true;
     
      return false;
    }

    public boolean test(Literal l1, Literal l2) {
      Object l1val = l1.getValue();
      Object l2val = l2.getValue();

      // String comparisons between ATerms
      if ( ( l1val instanceof ATermAppl ) && ( l2val instanceof ATermAppl) ) {
        ATermAppl l1term = (ATermAppl) l1val;
        ATermAppl l2term = (ATermAppl) l2val;
     
        String l1str = ATermUtils.getLiteralValue(l1term);
        String l2str = ATermUtils.getLiteralValue(l2term);
        String l1lang = ATermUtils.getLiteralLang( l1term );
        String l2lang = ATermUtils.getLiteralLang( l2term );
        String l1data = ATermUtils.getLiteralDatatype( l1term );
        String l2data = ATermUtils.getLiteralDatatype( l2term );
       
       
        if ( l1lang.equals( l2lang ) && l1data.equals( l2data ) ) {
          return comparesWell( l1str.compareTo( l2str ) );
        }
        return false;
      }
     
      // Numbers are a special case, since they can be promoted from
      // Integers and Decimals to Floats and Doubles.
      if ( ( l1val instanceof Number ) && ( l2val instanceof Number ) ) {
        NumericPromotion promoter = new NumericPromotion();
        Number l1num = (Number) l1val;
        Number l2num = (Number) l2val;

        promoter.promote(l1num, l2num);
        NumericComparisonVisitor visitor = new NumericComparisonVisitor();
        promoter.accept(visitor);

        return comparesWell( visitor.getComparison() );
      }

      final DatatypeReasoner dtr = l1.getABox().getDatatypeReasoner();
      final ATermAppl term1 = l1.getTerm();
      final ATermAppl type1 = (ATermAppl) term1.getArgument( ATermUtils.LIT_URI_INDEX );
      final ATermAppl type2 = (ATermAppl) l2.getTerm().getArgument( ATermUtils.LIT_URI_INDEX );
      try {
        /*
         * First check if the literals' datatypes are comparable. If so,
         * compile the comparison into a datatype reasoner
         * satisfiability check.
         */
        if( dtr.isSatisfiable( Arrays.asList( type1, type2 ) ) ) {
          Facet f = lt
            ? inclusive
              ? Facet.XSD.MIN_INCLUSIVE
              : Facet.XSD.MIN_EXCLUSIVE
            : inclusive
              ? Facet.XSD.MAX_INCLUSIVE
              : Facet.XSD.MAX_EXCLUSIVE;
          final ATermAppl canon1 = dtr.getCanonicalRepresentation( term1 );
          final ATermAppl baseType = (ATermAppl) canon1
              .getArgument( ATermUtils.LIT_URI_INDEX );
          final ATermAppl dr = ATermUtils
              .makeRestrictedDatatype( baseType, new ATermAppl[] { ATermUtils
                  .makeFacetRestriction( f.getName(), canon1 ) } );
          if( dtr.isSatisfiable( Collections.singleton( dr ), l2val ) )
            return true;
          else
            return false;
        }
        else
          return false;
      } catch( DatatypeReasonerException e ) {
        final String msg = format(
            "Unexpected datatype reasoner exception comparaing two literals ('%s','%s'). Treating as incomparable.",
            term1, l2.getTerm() );
        log.log( Level.WARNING, msg, e );
        return false;
      }
    }
  }

  public final static Tester equal = new EqualityTester(false),
      greaterThan = new OrderingTester(false, false),
      greaterThanOrEqual = new OrderingTester(false, true),
      lessThan = new OrderingTester(true, false),
      lessThanOrEqual = new OrderingTester(true, true),
      notEqual = new EqualityTester(true);
 
  /**
   * If the first argument is null, return the second.
   * Else, return the literal if its value equals the string.
   * Otherwise return null.
   */
  public static Literal expectedIfEquals( Literal expected, Literal result ) {
    if ( expected == null )
      return result;
   
    if ( ComparisonTesters.equal.test( new Literal[]{ expected, result } ) )
      return expected;
    return null;
  }
}
TOP

Related Classes of com.clarkparsia.pellet.rules.builtins.ComparisonTesters

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.