Package org.mindswap.pellet

Source Code of org.mindswap.pellet.Literal

// Portions Copyright (c) 2006 - 2008, Clark & Parsia, LLC.
// <http://www.clarkparsia.com>
// Clark & Parsia, LLC parts of this source code are 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
//
// ---
// Portions Copyright (c) 2003 Ron Alford, Mike Grove, Bijan Parsia, Evren Sirin
// Alford, Grove, Parsia, Sirin parts of this source code are available under
// the terms of the MIT License.
//
// The MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.

package org.mindswap.pellet;

import static java.lang.String.format;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import org.mindswap.pellet.exceptions.InternalReasonerException;
import org.mindswap.pellet.utils.ATermUtils;

import aterm.ATerm;
import aterm.ATermAppl;

import com.clarkparsia.pellet.datatypes.DatatypeReasoner;
import com.clarkparsia.pellet.datatypes.exceptions.DatatypeReasonerException;
import com.clarkparsia.pellet.datatypes.exceptions.InvalidLiteralException;
import com.clarkparsia.pellet.datatypes.exceptions.UnrecognizedDatatypeException;

/**
* @author Evren Sirin
*/
public class Literal extends Node {
  private ATermAppl  atermValue;

  private Object    value;

  // private Datatype datatype;

  private boolean    hasValue;

  private NodeMerge  merge;
 
  private boolean clashed = false;

  public Literal(ATermAppl name, ATermAppl term, ABox abox, DependencySet ds) {

    super( name, abox );

    if( term != null ) {
      hasValue = !term.getArgument( ATermUtils.LIT_URI_INDEX )
          .equals( ATermUtils.NO_DATATYPE );
      if( hasValue ) {
        try {
          value = abox.dtReasoner.getValue( term );
        } catch( InvalidLiteralException e ) {
          final String msg = format(
              "Attempt to create literal from invalid literal (%s): %s", term, e
                  .getMessage() );
          if( PelletOptions.INVALID_LITERAL_AS_INCONSISTENCY ) {
            log.fine( msg );
            value = null;
          }
          else {
            log.severe( msg );
            throw new InternalReasonerException( msg, e );
          }
        } catch( UnrecognizedDatatypeException e ) {
          final String msg = format(
              "Attempt to create literal from with unrecognized datatype (%s): %s",
              term, e.getMessage() );
          log.severe( msg );
          throw new InternalReasonerException( msg, e );
        }
        if( value == null ) {
          depends.put( name, ds );
        }
      }

      atermValue = ATermUtils.makeValue( term );
    }
        else {
          hasValue = false;
        }
  }

  public Literal(Literal literal, ABox abox) {
    super( literal, abox );

    atermValue = literal.atermValue;
    value = literal.value;
    hasValue = literal.hasValue;
  }

  @Override
    public DependencySet getNodeDepends() {
    return getDepends( ATermUtils.TOP_LIT );
  }

  @Override
    public Node copyTo(ABox abox) {
    return new Literal( this, abox );
  }

  @Override
    final public boolean isLeaf() {
    return true;
  }

  @Override
    public int getNominalLevel() {
    return isNominal()
      ? NOMINAL
      : BLOCKABLE;
  }

  @Override
    public boolean isNominal() {
    return (value != null);
  }

  @Override
    public boolean isBlockable() {
    return (value == null);
  }

  @Override
    public boolean isLiteral() {
    return true;
  }

  @Override
    public boolean isIndividual() {
    return false;
  }

  @Override
    public boolean isDifferent(Node node) {
    if( super.isDifferent( node ) ) {
          return true;
        }

    Literal literal = (Literal) node;
    if( hasValue && literal.hasValue ) {
      return value.getClass().equals( literal.value.getClass() )
          && !value.equals( literal.value );
    }

    return false;
  }

  @Override
    public boolean hasType(ATerm type) {
    if( type instanceof ATermAppl ) {
      final ATermAppl a = (ATermAppl) type;
      if( ATermUtils.isNominal( a ) ) {
        try {
          final ATermAppl input = (ATermAppl) a.getArgument( 0 );
          final ATermAppl canonical = abox.getDatatypeReasoner()
              .getCanonicalRepresentation( input );
          if( !canonical.equals( input ) ) {
                      type = ATermUtils.makeValue( canonical );
                    }
        } catch( InvalidLiteralException e ) {
          log
              .warning( format(
                  "hasType called with nominal using invalid literal ('%s'), returning false",
                  e.getMessage() ) );
          return false;
        } catch( UnrecognizedDatatypeException e ) {
          log
              .warning( format(
                  "hasType called with nominal using literal with unrecognized datatype ('%s'), returning false",
                  e.getMessage() ) );
          return false;
        }
      }
    }

    if( super.hasType( type ) ) {
          return true;
        }
        else if( hasValue ) {
      if( atermValue.equals( type ) ) {
              return true;
            }

      // Datatype datatype = abox.getDatatypeReasoner().getDatatype(
      // (ATermAppl) type );
      // if( datatype.contains( value ) )
      // return true;
    }

    return false;
  }

  @Override
    public DependencySet getDifferenceDependency(Node node) {
    DependencySet ds = null;
    if( isDifferent( node ) ) {
      ds = differents.get( node );
      if( ds == null ) {
              ds = DependencySet.INDEPENDENT;
            }
    }

    return ds;
  }

  @Override
    public void addType(ATermAppl c, DependencySet d) {
    if( hasType( c ) ) {
          return;
        }

    /*
     * A negated nominal is turned into a different
     */
    if( ATermUtils.isNot( c ) ) {
      final ATermAppl arg = (ATermAppl) c.getArgument( 0 );
      if( ATermUtils.isNominal( arg ) ) {
        final ATermAppl v = (ATermAppl) arg.getArgument( 0 );
        Literal other = abox.getLiteral( v );
        if( other == null ) {
                  other = abox.addLiteral( v, d );
                }
        super.setDifferent( other, d );
        return;
      }
    }
    super.addType( c, d );

    // TODO when two literals are being merged this is not efficient
    // if(abox.isInitialized())
    checkClash();
  }

  public void addAllTypes(Map<ATermAppl, DependencySet> types, DependencySet ds) {
    for( Entry<ATermAppl, DependencySet> entry : types.entrySet() ) {
      ATermAppl c = entry.getKey();

      if( hasType( c ) ) {
              continue;
            }

      DependencySet depends = entry.getValue();

      super.addType( c, depends.union( ds, abox.doExplanation() ) );
    }

    checkClash();
  }

  @Override
    public boolean hasSuccessor(Node x) {
    return false;
  }

  @Override
    public final Literal getSame() {
    return (Literal) super.getSame();
  }

  @Override
    public ATermAppl getTerm() {
    return hasValue
      ? (ATermAppl) atermValue.getArgument( 0 )
      : null;
  }

  public String getLang() {
    return hasValue
      ? ((ATermAppl) ((ATermAppl) atermValue.getArgument( 0 ))
          .getArgument( ATermUtils.LIT_LANG_INDEX )).getName()
      : "";
  }

  public String getLexicalValue() {
    if( hasValue ) {
          return value.toString();
        }

    return null;
  }
 
  void reportClash(Clash clash) {
    clashed = true;
    abox.setClash( clash );
  }

  private void checkClash() {
    clashed = false;
   
    if( hasValue && value == null ) {
      reportClash( Clash.invalidLiteral( this, getDepends( name ), getTerm() ) );
      return;
    }

    if( hasType( ATermUtils.BOTTOM_LIT ) ) {
      reportClash( Clash.emptyDatatype( this, getDepends( ATermUtils.BOTTOM_LIT ) ) );
      if( abox.doExplanation() ) {
              System.out.println( "1) Literal clash dependency = " + abox.getClash() );
            }
      return;
    }

    final Set<ATermAppl> types = getTypes();
    final DatatypeReasoner dtReasoner = abox.getDatatypeReasoner();

    try {
      if( hasValue ) {

        if( !dtReasoner.isSatisfiable( types, value ) ) {
          ArrayList<ATermAppl> primitives = new ArrayList<ATermAppl>();
          for( ATermAppl t : types ) {
            if( ATermUtils.TOP_LIT.equals( t ) ) {
                          continue;
                        }
                        else {
                          primitives.add( t );
                        }
          }

          final ATermAppl dt[] = primitives
              .toArray( new ATermAppl[primitives.size() - 1] );

          DependencySet ds = DependencySet.EMPTY;
          for( int i = 0; i < dt.length; i++ ) {
            ds = ds.union( getDepends( dt[i] ), abox.doExplanation() );
            if (abox.doExplanation()) {
              ATermAppl dtName = ATermUtils.isNot(dt[i]) ? (ATermAppl) dt[i].getArgument(0) : dt[i];
              ATermAppl definition = dtReasoner.getDefinition(dtName);
              if (definition != null) {
                              ds = ds.union(Collections.singleton(ATermUtils.makeDatatypeDefinition(dtName, definition)), true);
                            }
            }
          }

          reportClash( Clash.valueDatatype( this, ds, (ATermAppl) atermValue.getArgument(0), dt[0] ) );
        }
      }
      else {
        if( dtReasoner.isSatisfiable( types ) ) {
          if ( !dtReasoner.containsAtLeast( 2, types ) ) {
            /*
             * This literal is a variable, but given current ranges can only
             * take on a single value.  Merge with that value.
             */
            final Object value = dtReasoner.valueIterator( types ).next();
            final ATermAppl valueTerm = dtReasoner.getLiteral( value );
            Literal valueLiteral = abox.getLiteral( valueTerm );
            if (valueLiteral == null) {
              /*
               * No dependency set is used here because omitting it prevents the
               * constant literal from being removed during backtrack
               */
              valueLiteral = abox.addLiteral( valueTerm );
            }
            DependencySet mergeDs = DependencySet.INDEPENDENT;
            for ( DependencySet ds : depends.values() ) {
                          mergeDs = mergeDs.union( ds, abox.doExplanation() );
                        }
            merge = new NodeMerge( this, valueLiteral, mergeDs );
          }
        } else {
          ArrayList<ATermAppl> primitives = new ArrayList<ATermAppl>();
          for( ATermAppl t : types ) {
            if( ATermUtils.TOP_LIT.equals( t ) ) {
                          continue;
                        }
                        else {
                          primitives.add( t );
                        }
          }

          final ATermAppl dt[] = primitives
              .toArray( new ATermAppl[primitives.size() - 1] );

          DependencySet ds = DependencySet.EMPTY;
          for( int i = 0; i < dt.length; i++ ) {
                      ds = ds.union( getDepends( dt[i] ), abox.doExplanation() );
              if (abox.doExplanation()) {
              ATermAppl definition = dtReasoner.getDefinition(dt[i]);
              if (definition != null) {
                              ds = ds.union(Collections.singleton(ATermUtils.makeDatatypeDefinition(dt[i], definition)), true);
                            }
            }
                    }

          reportClash( Clash.emptyDatatype( this, ds, dt ) );
        }
      }
    } catch( DatatypeReasonerException e ) {
      final String msg = "Unexcepted datatype reasoner exception: " + e.getMessage();
      log.severe( msg );
      throw new InternalReasonerException( msg, e );
    }
  }

  public Object getValue() {
    return value;
  }

  @Override
    public boolean restore(int branch) {
    Boolean restorePruned = restorePruned( branch );
    if( Boolean.FALSE.equals( restorePruned ) ) {
          return restorePruned;
        }

    boolean restored = Boolean.TRUE.equals( restorePruned );

    restored |= super.restore( branch );
   
    if (clashed) {
      checkClash();
    }

    return restored;
  }

  @Override
    final public void prune(DependencySet ds) {
    pruned = ds;
  }

  @Override
    public void unprune(int branch) {
    super.unprune( branch );

    checkClash();
  }

  public String debugString() {
    return name + " = " + getTypes().toString();
  }

  public NodeMerge getMergeToConstant() {
    return merge;
  }

  public void clearMergeToConstant() {
    merge = null;
  }
}
TOP

Related Classes of org.mindswap.pellet.Literal

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.