
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