All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.maven.mercury.metadata.sat.HelpingSatSolver Maven / Gradle / Ivy

The newest version!
/**
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */
package org.apache.maven.mercury.metadata.sat;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.maven.mercury.artifact.ArtifactMetadata;
import org.apache.maven.mercury.artifact.MetadataTreeNode;
import org.apache.maven.mercury.event.EventManager;
import org.apache.maven.mercury.event.EventTypeEnum;
import org.apache.maven.mercury.event.GenericEvent;
import org.apache.maven.mercury.event.MercuryEventListener;
import org.apache.maven.mercury.logging.IMercuryLogger;
import org.apache.maven.mercury.logging.MercuryLoggerManager;
import org.apache.maven.mercury.metadata.MetadataTreeNodeGAComparator;
import org.apache.maven.mercury.metadata.MetadataTreeNodeGAVComparator;
import org.codehaus.plexus.lang.DefaultLanguage;
import org.codehaus.plexus.lang.Language;
import org.sat4j.core.Vec;
import org.sat4j.core.VecInt;
import org.sat4j.pb.IPBSolver;
import org.sat4j.pb.ObjectiveFunction;
import org.sat4j.pb.SolverFactory;
import org.sat4j.specs.ContradictionException;
import org.sat4j.specs.IConstr;
import org.sat4j.specs.IVec;
import org.sat4j.specs.IVecInt;
import org.sat4j.specs.TimeoutException;

/**
 * Default SAT4J implementation.
 * 
 * @author Oleg Gusakov
 * @version $Id: HelpingSatSolver.java 762963 2009-04-07 21:01:07Z ogusakov $
 */
public class HelpingSatSolver
{}
//implements SatSolver
//{
//  private static final IMercuryLogger LOG = MercuryLoggerManager.getLogger( HelpingSatSolver.class ); 
//  private static final Language LANG = new DefaultLanguage( HelpingSatSolver.class );
//  
//  private DependencyHelper _helper = new DependencyHelper( SolverFactory.newEclipseP2() );
//  protected MetadataTreeNode _root;
//  
//  protected EventManager _eventManager;
//  
//  protected static final Comparator gaComparator = new MetadataTreeNodeGAComparator();
//  //-----------------------------------------------------------------------
//  public static SatSolver create( MetadataTreeNode tree )
//  throws SatException
//  {
//    return new HelpingSatSolver( tree );
//  }
//  //-----------------------------------------------------------------------
//  public static SatSolver create( MetadataTreeNode tree, EventManager eventManager )
//  throws SatException
//  {
//    return new HelpingSatSolver( tree, eventManager );
//  }
//  //-----------------------------------------------------------------------
//  public HelpingSatSolver( MetadataTreeNode tree, EventManager eventManager )
//  throws SatException
//  {
//    this._eventManager = eventManager;
//    GenericEvent event = null;
//    
//    if( tree == null)
//      throw new SatException( LANG.getMessage( "null.tree.arg" ) );
//    
//    try
//    {
//      if( _eventManager != null )
//        event = new GenericEvent( EventTypeEnum.satSolver, EVENT_CREATE_SOLVER, tree.toString() );
//        
//      if( tree.getId() == 0 )
//        MetadataTreeNode.reNumber( tree, 1 );
//      
//      int nNodes = tree.countDistinctNodes();
//  
//      LOG.debug( "SatContext: # of variables: "+nNodes );
//  
//      _root = tree;
//      
//      try
//      {
//        addNode( tree );
//      }
//      catch (ContradictionException e)
//      {
//        throw new SatException(e);
//      }
//    }
//    finally
//    {
//      if( _eventManager != null )
//      {
//        event.stop();
//        _eventManager.fireEvent( event );
//      }
//    }
//  }
//  //-----------------------------------------------------------------------
//  public HelpingSatSolver( MetadataTreeNode tree )
//  throws SatException
//  {
//    this( tree, null );
//  }
//  //-----------------------------------------------------------------------
//  public final void applyPolicies( List> comparators )
//  throws SatException
//  {
//    if( comparators == null || comparators.size() < 1 )
//      return;
//    
//    if( _root == null )
//      throw new SatException( "cannot apply policies to a null tree" );
//    
//    // TODO og: assumption - around 128 GA's per tree. If more - map reallocates - slow down.
//    // TODO og: MERCURY-40
//    Map> buckets = new LinkedHashMap>(128);
//    fillBuckets( buckets, _root );
//    sortBuckets( buckets, comparators );
//    useBuckets( buckets );
//  }
//  //-----------------------------------------------------------------------
//  private void useBuckets( Map> buckets )
//  throws SatException
//  {
//    if( buckets == null || buckets.size() < 1 )
//      return;
//    
//    IVecInt vars            = new VecInt( 128 );
//    IVec coeffs = new Vec( 128 );
//    
//    int count = 0;
//    
//    for( String key : buckets.keySet() )
//    {
//      List bucket = buckets.get( key );
//  
//// oleg: ? this is needed if optimization is "maximize"       
////      Collections.reverse(  bucket );
//      
//      int bucketSize = bucket.size(); 
//      
//      boolean bigBucket = bucketSize > 1;
//
//if( LOG.isDebugEnabled() )
//    LOG.debug( "\n\nBucket "+key );
//
//      IVecInt bucketVars = new VecInt( bucketSize );
//      
//      for( int i=0; i> buckets
//      , List> comparators
//                                          )
//  {
//    Comparator lastComparator;
//    for( List bucket : buckets.values() )
//    {
//      lastComparator = gaComparator;
//      for( Comparator comparator : comparators )
//      {
//        sortBucket( bucket, comparator, lastComparator );
//        lastComparator = comparator;
//      }
//      // due to the nature of Comparator need to reverse the result
//      // as the best fit is now last
//      Collections.reverse( bucket );
//
//      // the best fit now first, and we don't need duplicate GAVs
//      removeDuplicateGAVs( bucket );
//
//    }
//  }
//  //-----------------------------------------------------------------------
//  // remove duplicates, preserving the order. The first one is the most fit,
//  // so need to delete from tail
//  protected static final void removeDuplicateGAVs( List bucket )
//  {
//    if( bucket == null || bucket.size() < 2 )
//      return;
//
//    Comparator gav = new MetadataTreeNodeGAVComparator();
//    
//    int len = bucket.size();
//    int [] dups = new int[ len-1 ];
//    int cnt = 0;
//    
//    for( int i=1; i 0 )
//      for( int i=0; i bucket
//               , Comparator comparator
//               , Comparator lastComparator
//               )
//  {
//    if( bucket == null || bucket.size() < 2 )
//      return;
//    
//    int bLen = bucket.size();
//    MetadataTreeNode [] temp = bucket.toArray( new MetadataTreeNode[ bLen ] );
//    
//    int wStart = -1;
//    int wLen = 0;
//    MetadataTreeNode [] work = new MetadataTreeNode[ bLen ];
//    
//    MetadataTreeNode lastNode = null;
//    for( int i=0; i 0 ) // eq list formed
//      {
//        reorder( work, wLen, comparator );
//        for( int j=0; j comparator
//                                   )
//  {
//    MetadataTreeNode[] temp = new MetadataTreeNode[ wLen ];
//    
//    for( int i=0; i< wLen; i++ )
//      temp[i] = work[i];
//    
//    Arrays.sort( temp, comparator );
//    
//    for( int i=0; i> buckets
//      , MetadataTreeNode node
//                          )
//  {
//    String ga = node.getMd().getGA();
//    List bucket = buckets.get(ga);
//    if( bucket == null )
//    {
//      // TODO og: assumption - around 32 GAVs per GA
//      bucket = new ArrayList( 32 );
//      buckets.put( ga, bucket );
//    }
//    
//    bucket.add( node );
//    
//    if( ! node.hasChildren() )
//      return;
//    
//    for( MetadataTreeNode kid : node.getChildren() )
//    {
//      fillBuckets( buckets, kid );
//    }
//  }
//  //-----------------------------------------------------------------------
//  private final void addPB( IVecInt lits, IVec coeff, boolean ge, BigInteger cardinality )
//  throws ContradictionException
//  {
//    _solver.addPseudoBoolean( lits, coeff, ge, cardinality );
//    
//if( LOG.isDebugEnabled() )
//  LOG.debug("PB: ");
//    
//    for( int i=0; i= " : " < ")+" "+cardinality );
//  }
//  //-----------------------------------------------------------------------
//  private final Map> processChildren(
//                                                        List queries
//                                                        , List children
//                                                                              )
//  throws SatException
//  {
//    if( queries == null || queries.size() < 1 )
//      return null;
//    
//    if( children == null || children.size() < 1 )
//      throw new SatException("there are queries, but not results. Queries: "+queries);
//    
//    // TODO og: MERCURY-40
//    Map> res = new LinkedHashMap>( queries.size() );
//
//    for( ArtifactMetadata q : queries )
//    {
//      List bucket = new ArrayList(4);
//      String queryGA = q.getGA();
//      
//      for( MetadataTreeNode tn : children )
//      {
//        if( tn.getMd() == null )
//          throw new SatException("resulting tree node without metadata for query "+q );
//        
//        if( queryGA.equals( tn.getMd().getGA()) )
//        {
//          bucket.add(tn);
//        }
//      }
//      
//      if( bucket.size() < 1 )
//        throw new SatException("No children for query "+queryGA );
//      
//      res.put( q, bucket );
//    }
//
//    return res;
//  } 
//  //-----------------------------------------------------------------------
//  private final void addNode( MetadataTreeNode node )
//  throws ContradictionException, SatException
//  {
//    if( node == null )
//      return;
//    
//    if( node.getMd() == null )
//      throw new SatException("found a node without metadata");
//    
//    // this one is a must :)
//    if( node.getParent() == null )
//      _helper.setTrue( node, node.getName() );
//    
//    if( ! node.hasChildren() )
//      return;
//    
//    Map> kids = processChildren( node.getQueries(), node.getChildren() );
//    
//    // leaf node in this scope
//    if( kids == null )
//      return;
//    
//    for( Map.Entry> kid : kids.entrySet() )
//    {
//      ArtifactMetadata query = kid.getKey();
//      
//      List range = kid.getValue();
//
//      if( range.size() > 1 )
//      {
//        addRange( nodeLit.getLiteral(), range, query.isOptional() );
//        for( MetadataTreeNode tn : range )
//        {
//          addNode( tn );
//        }
//      }
//      else
//      {
//        MetadataTreeNode child = range.get(0);
//        SatVar kidLit = _context.findOrAdd( child );
//        
//        addPB( SatHelper.getSmallOnes( new int [] { nodeLit.getLiteral(), kidLit.getLiteral() } )
//            , SatHelper.getBigOnes( 1, -1 )
//            , true, BigInteger.ZERO
//            );
////        addRange( nodeLit.getLiteral(), range, query.isOptional() );
//        addNode( child );
//      }
//
//    }
//  }
//  //-----------------------------------------------------------------------
//  private final int [] addRange( int parentLiteral, List range, boolean optional )
//  throws ContradictionException, SatException
//  {
//    SatVar literal;
//    
//    int [] literals = new int[ range.size() ];
//    
//    int count = 0;
//    
//    for( MetadataTreeNode tn : range )
//    {
//      literal = _context.findOrAdd( tn );
//      literals[count++] = literal.getLiteral();
//
//      // implication to parent
//      addPB( SatHelper.getSmallOnes( new int [] { parentLiteral, literal.getLiteral() } )
//          , SatHelper.getBigOnes( 1, -1 )
//          , true, BigInteger.ZERO
//          );
//    }
//    
//    IVecInt rangeVector = SatHelper.getSmallOnes( literals );
//    
//    if( optional ) // Sxi >= 0
//    {
//if( LOG.isDebugEnabled() )
//  LOG.debug( "optional range: atMost 1: "+ SatHelper.vectorToString( rangeVector) );
//    
//      _solver.addAtMost( rangeVector, 1 );
//    }
//    else // Sxi = 1
//    {
//if( LOG.isDebugEnabled() )
//  LOG.debug( "range: " + SatHelper.vectorToString( rangeVector) );
//
//    IConstr atLeast = _solver.addAtLeast( rangeVector, 1 );
//    if( LOG.isDebugEnabled() )
//      LOG.debug( "atLeast: " + SatHelper.vectorToString( atLeast) );
//
//    IConstr atMost  = _solver.addAtMost( rangeVector, 1 );
//    if( LOG.isDebugEnabled() )
//      LOG.debug( "atMost: " + SatHelper.vectorToString( atMost) );
//
//    }
//    
//    return literals;
//  }
//  //-----------------------------------------------------------------------
//  public final List solve()
//  throws SatException
//  {
//    List res = null;
//    GenericEvent event = null;
//    
//    try
//    {
//      if( _eventManager != null )
//        event = new GenericEvent( EventTypeEnum.satSolver, EVENT_SOLVE, _root.toString() );
//      
//      if( _solver.isSatisfiable() )
//      {
//        res = new ArrayList( _root.countNodes() );
//        
//        int [] model = _solver.model();
//
//if( LOG.isDebugEnabled() )
//  if( model != null )
//  {
//    StringBuilder sb = new StringBuilder();
//    String comma = "";
//    for( int m : model )
//    {
//      sb.append( comma+m );
//      comma = ", ";
//    }
//    LOG.debug( '['+sb.toString()+']' );
//  }
//  else 
//    LOG.debug( "model is null" );
//
//        for( int i : model )
//          if( i > 0 )
//            res.add( _context.getMd( i ) );
//      }
//    }
//    catch (TimeoutException e)
//    {
//      throw new SatException( e );
//    }
//    finally
//    {
//      if( _eventManager != null )
//      {
//        event.stop();
//        _eventManager.fireEvent( event );
//      }
//    }
//    return res;
//  }
//  //-----------------------------------------------------------------------
//  public final MetadataTreeNode solveAsTree()
//  throws SatException
//  {
//    try
//    {
//      if( _helper.hasASolution() )
//      {
//          
//         IVec solution = _helper.getSolution();
//         
//         if( solution == null )
//             return null;
//         
//         for( Iterator i = solution.iterator(); i.hasNext(); )
//         {
//             MetadataTreeNode mtn = i.next();
//             
//             if( mtn.getParent() == null )
//                 return mtn;
//         }
//         
//      return null;
//      }
//    }
//    catch (TimeoutException e)
//    {
//      throw new SatException( e );
//    }
//    
//  }
//  //-----------------------------------------------------------------------
//  public void register( MercuryEventListener listener )
//  {
//    if( _eventManager == null )
//      _eventManager = new EventManager();
//
//    _eventManager.register( listener );
//  }
//
//  public void setEventManager( EventManager eventManager )
//  {
//    _eventManager = eventManager;
//  }
//
//  public void unRegister( MercuryEventListener listener )
//  {
//    if( _eventManager != null )
//      _eventManager.unRegister( listener );
//  }
//  //-----------------------------------------------------------------------
//}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy