Package org.mindswap.pellet.tableau.branch

Source Code of org.mindswap.pellet.tableau.branch.MaxBranch

// 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.tableau.branch;

import java.util.logging.Level;

import java.util.List;

import org.mindswap.pellet.ABox;
import org.mindswap.pellet.Clash;
import org.mindswap.pellet.DependencySet;
import org.mindswap.pellet.Edge;
import org.mindswap.pellet.EdgeList;
import org.mindswap.pellet.Individual;
import org.mindswap.pellet.Node;
import org.mindswap.pellet.NodeMerge;
import org.mindswap.pellet.PelletOptions;
import org.mindswap.pellet.Role;
import org.mindswap.pellet.exceptions.InternalReasonerException;
import org.mindswap.pellet.tableau.completion.CompletionStrategy;
import org.mindswap.pellet.tableau.completion.queue.NodeSelector;
import org.mindswap.pellet.tableau.completion.queue.QueueElement;
import org.mindswap.pellet.utils.ATermUtils;

import aterm.ATermAppl;



public class MaxBranch extends IndividualBranch {
  private List<NodeMerge> mergePairs;
  private Role r;
  private int n;
  private ATermAppl qualification;
  private DependencySet[] prevDS;

  public MaxBranch(ABox abox, CompletionStrategy strategy, Individual x, Role r, int n, ATermAppl qualification, List<NodeMerge> mergePairs, DependencySet ds) {
    super(abox, strategy, x, ds, mergePairs.size());
   
    this.r = r;
    this.n = n;
    this.mergePairs = mergePairs;
    this.qualification = qualification;
        this.prevDS = new DependencySet[mergePairs.size()];
  }   
   
  public IndividualBranch copyTo(ABox abox) {
      Individual x = abox.getIndividual(ind.getName());
      MaxBranch b = new MaxBranch(abox, null, x, r, n, qualification, mergePairs, getTermDepends());
      b.setAnonCount( getAnonCount() );
      b.setNodeCount( nodeCount );
      b.setBranch( branch );
      b.setStrategy( strategy );
        b.setTryNext( tryNext );
        b.prevDS = new DependencySet[prevDS.length];
        System.arraycopy(prevDS, 0, b.prevDS, 0, getTryNext() );
       
      return b;
  }
 
  protected void tryBranch() {   
    abox.incrementBranch();
   
    //we must re-add this individual to the max queue. This is because we may still need to keep
    //applying the max rule for additional merges   
    //recreate the label for the individuals
    ATermAppl maxCon = ATermUtils.makeMax(this.r.getName(), this.n, this.qualification);
    //normalize the label
    maxCon = ATermUtils.normalize(maxCon);
   
    if( PelletOptions.USE_COMPLETION_QUEUE ) {
      QueueElement qElement = new QueueElement( ind, maxCon );
      abox.getCompletionQueue().add( qElement, NodeSelector.MAX_NUMBER );
      abox.getCompletionQueue().add( qElement, NodeSelector.CHOOSE );
    }
   
   
    DependencySet ds = getTermDepends();     
    for(; getTryNext() < getTryCount(); tryNext++) {   
      this.abox.getKB().timers.mainTimer.check();
      if(PelletOptions.USE_SEMANTIC_BRANCHING) {
        for(int m = 0; m < getTryNext(); m++) {
          NodeMerge nm = mergePairs.get(m);     
          Node y = abox.getNode(nm.getSource()).getSame();
          Node z = abox.getNode(nm.getTarget()).getSame();
          strategy.setDifferent(y, z, prevDS[m]);
          //strategy.addType( y, ATermUtils.makeNot( ATermUtils.makeValue( z.getName() ) ), prevDS[m] );
        }
      }
     
      NodeMerge nm = mergePairs.get(getTryNext());     
      Node y = abox.getNode(nm.getSource()).getSame();
      Node z = abox.getNode(nm.getTarget()).getSame();
           
      if( log.isLoggable( Level.FINE ) )
                log.fine(
            "MAX : (" + (getTryNext()+1) + "/" + mergePairs.size() +
            ") at branch (" + getBranch() + ") to  " + ind +
            " for prop " + r + " qualification " + qualification +
            " merge " + y + " -> " + z + " " + ds);           
     
      ds = ds.union(new DependencySet(getBranch()), abox.doExplanation());
     
      // max cardinality merge also depends on all the edges
      // between the individual that has the cardinality and
      // nodes that are going to be merged
      EdgeList rNeighbors = ind.getRNeighborEdges(r);
      boolean yEdge = false, zEdge = false;
      for( Edge edge : rNeighbors ) {
        Node neighbor = edge.getNeighbor( ind );
       
        if( neighbor.equals( y ) ) {
          ds = ds.union( edge.getDepends(), abox.doExplanation() );
          yEdge = true;
        }
        else if( neighbor.equals( z ) ) {
          ds = ds.union( edge.getDepends(), abox.doExplanation() );
          zEdge = true;
        }
      }
     
      // if there is no edge coming into the node that is
      // going to be merged then it is not possible that
      // they are affected by the cardinality restriction
      // just die instead of possibly unsound results
      if(!yEdge || !zEdge)
          throw new InternalReasonerException(
              "An error occurred related to the max cardinality restriction about "  + r);
     
      // if the neighbor nodes did not have the qualification
      // in their type list they would have not been affected
      // by the cardinality restriction. so this merges depends
      // on their types
      ds = ds.union( y.getDepends( qualification ), abox.doExplanation() );
      ds = ds.union( z.getDepends( qualification ), abox.doExplanation() );
     
            // if there were other merges based on the exact same cardinality
      // restriction then this merge depends on them, too (we wouldn't
      // have to merge these two nodes if the previous merge did not
      // eliminate some other possibilities)
          for( int b = abox.getBranches().size() -2; b >=0; b-- ) {
            Branch branch = abox.getBranches().get( b );
            if( branch instanceof MaxBranch ) {
              MaxBranch prevBranch = (MaxBranch) branch;
              if( prevBranch.ind.equals( ind )
                && prevBranch.r.equals( r )
                && prevBranch.qualification.equals( qualification ) ) {
                ds.add( prevBranch.getBranch() );
              }
              else {
                break;
              }
            }
            else
              break;
          }
     
      strategy.mergeTo(y, z, ds);

//      abox.validate();
     
      boolean earlyClash = abox.isClosed();
      if(earlyClash) {
        if( log.isLoggable( Level.FINE ) )
                    log.fine("CLASH: Branch " + getBranch() + " " + abox.getClash() + "!");

        DependencySet clashDepends = abox.getClash().getDepends();
       
        if(clashDepends.contains(getBranch())) {
          // we need a global restore here because the merge operation modified three
          // different nodes and possibly other global variables
          strategy.restore(this);
         
          // global restore sets the branch number to previous value so we need to
          // increment it again
          abox.incrementBranch();
                 
                    setLastClash( clashDepends );
        }
        else
          return;
      }
      else
        return
    }
   
        ds = getCombinedClash();
       
        //CHW - removed for rollback through deletions
        if(!PelletOptions.USE_INCREMENTAL_DELETION)
            ds.remove( getBranch() );
       
    if(abox.doExplanation())
        abox.setClash(Clash.maxCardinality(ind, ds, r.getName(), n));
    else
        abox.setClash(Clash.maxCardinality(ind, ds));
 
    return;
  }
 
    public void setLastClash( DependencySet ds ) {
        super.setLastClash( ds );
        if(getTryNext()>=0)
            prevDS[getTryNext()] = ds;
    }
 
  public String toString() {
    if(getTryNext() < mergePairs.size())
      return "Branch " + getBranch() + " max rule on " + ind + " merged  " + mergePairs.get(getTryNext());
   
    return "Branch " + getBranch() + " max rule on " + ind + " exhausted merge possibilities";
  }
 
 
 
  /**
   * Added for to re-open closed branches.
   * This is needed for incremental reasoning through deletions
   *
   * @param index The shift index
   */
  public void shiftTryNext(int openIndex){
    //save vals
//    DependencySet preDS = prevDS[openIndex];

    //re-open the merge pair
    NodeMerge nm = mergePairs.remove(openIndex);
    mergePairs.add(nm);   

    //shift the previous ds
    for(int i = openIndex; i < mergePairs.size(); i++){
      prevDS[i] = prevDS[i+1];
    }

    //move open label to end
    prevDS[mergePairs.size()-1] = null;
   
    //decrement trynext
    setTryNext( getTryNext() - 1 );   
  }
 
}
TOP

Related Classes of org.mindswap.pellet.tableau.branch.MaxBranch

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.