Author: jvanzyl Date: Thu Jun 12 17:12:46 2008 New Revision: 667301 URL: http://svn.apache.org/viewvc?rev=667301&view=rev Log: MARTIFACT-20: revised use of the implementation based on feedback from Daniel Le Berre from SAT4J Submitted by: Oleg Gusakov
Removed: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/SatClause.java maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/SatConstraint.java maven/sandbox/trunk/mercury/src/test/java/org/apache/maven/mercury/metadata/sat/SatFeedTest.java Modified: maven/sandbox/trunk/mercury/lib/install.sh maven/sandbox/trunk/mercury/lib/org.sat4j.core.jar maven/sandbox/trunk/mercury/lib/org.sat4j.pb.jar maven/sandbox/trunk/mercury/pom.xml maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/ArtifactMetadata.java maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/DefaultMetadataResolver.java maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/MetadataGraph.java maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/MetadataTreeNode.java maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/DefaultSatSolver.java maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/SatContext.java maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/SatHelper.java maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/SatSolver.java maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/SatVar.java maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/transform/ClasspathContainer.java maven/sandbox/trunk/mercury/src/test/java/org/apache/maven/mercury/metadata/sat/DefaultSatSolverTest.java Modified: maven/sandbox/trunk/mercury/lib/install.sh URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/lib/install.sh?rev=667301&r1=667300&r2=667301&view=diff ============================================================================== --- maven/sandbox/trunk/mercury/lib/install.sh (original) +++ maven/sandbox/trunk/mercury/lib/install.sh Thu Jun 12 17:12:46 2008 @@ -1,2 +1,2 @@ -mvn install:install-file -Dfile=org.sat4j.core.jar -DgroupId=org.sat4j -Dpackaging=jar -DartifactId=org.sat4j.core -Dversion=2.0.0.v20080430 -DgeneratePom=true -DgenerateChecksum=true -mvn install:install-file -Dfile=org.sat4j.pb.jar -DgroupId=org.sat4j -Dpackaging=jar -DartifactId=org.sat4j.pb -Dversion=2.0.0.v20080430 -DgeneratePom=true -DgenerateChecksum=true +mvn install:install-file -Dfile=org.sat4j.core.jar -DgroupId=org.sat4j -Dpackaging=jar -DartifactId=org.sat4j.core -Dversion=2.0.0 -DgeneratePom=true -DgenerateChecksum=true +mvn install:install-file -Dfile=org.sat4j.pb.jar -DgroupId=org.sat4j -Dpackaging=jar -DartifactId=org.sat4j.pb -Dversion=2.0.0 -DgeneratePom=true -DgenerateChecksum=true Modified: maven/sandbox/trunk/mercury/lib/org.sat4j.core.jar URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/lib/org.sat4j.core.jar?rev=667301&r1=667300&r2=667301&view=diff ============================================================================== Binary files - no diff available. Modified: maven/sandbox/trunk/mercury/lib/org.sat4j.pb.jar URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/lib/org.sat4j.pb.jar?rev=667301&r1=667300&r2=667301&view=diff ============================================================================== Binary files - no diff available. Modified: maven/sandbox/trunk/mercury/pom.xml URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/pom.xml?rev=667301&r1=667300&r2=667301&view=diff ============================================================================== --- maven/sandbox/trunk/mercury/pom.xml (original) +++ maven/sandbox/trunk/mercury/pom.xml Thu Jun 12 17:12:46 2008 @@ -118,12 +118,12 @@ <dependency> <groupId>org.sat4j</groupId> <artifactId>org.sat4j.core</artifactId> - <version>2.0.0.v20080430</version> + <version>2.0.0</version> </dependency> <dependency> <groupId>org.sat4j</groupId> <artifactId>org.sat4j.pb</artifactId> - <version>2.0.0.v20080430</version> + <version>2.0.0</version> </dependency> <!-- Test Dependencies --> <dependency> Modified: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/ArtifactMetadata.java URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/ArtifactMetadata.java?rev=667301&r1=667300&r2=667301&view=diff ============================================================================== --- maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/ArtifactMetadata.java (original) +++ maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/ArtifactMetadata.java Thu Jun 12 17:12:46 2008 @@ -26,6 +26,8 @@ protected ArtifactScopeEnum artifactScope; protected String classifier; + + protected boolean optional; /** * explanation: why this MD was chosen over it's siblings @@ -162,6 +164,16 @@ ; } + public String getGA() + { + return toDomainString(); + } + + public String getGAV() + { + return toString(); + } + @Override public String toString() { @@ -332,4 +344,14 @@ { return groupId + ":" + artifactId; } + public boolean isOptional() + { + return optional; + } + public void setOptional(boolean optional) + { + this.optional = optional; + } + + } Modified: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/DefaultMetadataResolver.java URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/DefaultMetadataResolver.java?rev=667301&r1=667300&r2=667301&view=diff ============================================================================== --- maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/DefaultMetadataResolver.java (original) +++ maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/DefaultMetadataResolver.java Thu Jun 12 17:12:46 2008 @@ -82,25 +82,22 @@ found.setArtifactUri( pomArtifact.getFile().toURI().toString() ); } - MetadataTreeNode node = new MetadataTreeNode( found, parent, true, found.getScopeAsEnum() ); + MetadataTreeNode node = new MetadataTreeNode( found, parent, query, true, found.getScopeAsEnum() ); Collection<ArtifactMetadata> dependencies = metadataResolution.getArtifactMetadata().getDependencies(); if ( dependencies != null && dependencies.size() > 0 ) { - int numberOfChildren = dependencies.size(); - node.setNChildren( numberOfChildren ); - int kidNo = 0; for ( ArtifactMetadata a : dependencies ) { MetadataTreeNode kidNode = resolveMetadataTree( a, node, localRepository, remoteRepositories ); - node.addChild( kidNo++, kidNode ); + node.addChild( kidNode ); } } return node; } else { - return new MetadataTreeNode( pomArtifact, parent, false, query.getArtifactScope() ); + return new MetadataTreeNode( new ArtifactMetadata(pomArtifact), parent, query, false, query.getArtifactScope() ); } } catch ( Exception anyEx ) Modified: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/MetadataGraph.java URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/MetadataGraph.java?rev=667301&r1=667300&r2=667301&view=diff ============================================================================== --- maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/MetadataGraph.java (original) +++ maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/MetadataGraph.java Thu Jun 12 17:12:46 2008 @@ -1,6 +1,7 @@ package org.apache.maven.mercury.metadata; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -140,15 +141,15 @@ entry = vertex; } - MetadataTreeNode[] kids = node.getChildren(); - if ( kids == null || kids.length < 1 ) + List<MetadataTreeNode> kids = node.getChildren(); + if ( kids == null || kids.size() < 1 ) { return; } - for( int i = 0; i< kids.length; i++ ) + for( int i = 0; i< kids.size(); i++ ) { - MetadataTreeNode n = kids[i]; + MetadataTreeNode n = kids.get(i); processTreeNodes( vertex, n, depth + 1, i ); } } @@ -336,8 +337,8 @@ } int count = 1; - MetadataTreeNode[] kids = tree.getChildren(); - if ( kids == null || kids.length < 1 ) + List<MetadataTreeNode> kids = tree.getChildren(); + if ( kids == null || kids.size() < 1 ) { return count; } Modified: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/MetadataTreeNode.java URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/MetadataTreeNode.java?rev=667301&r1=667300&r2=667301&view=diff ============================================================================== --- maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/MetadataTreeNode.java (original) +++ maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/MetadataTreeNode.java Thu Jun 12 17:12:46 2008 @@ -1,5 +1,8 @@ package org.apache.maven.mercury.metadata; +import java.util.ArrayList; +import java.util.List; + import org.apache.maven.mercury.Artifact; import org.apache.maven.mercury.ArtifactScopeEnum; /** @@ -11,28 +14,50 @@ public class MetadataTreeNode { - ArtifactMetadata md; // this node - - MetadataTreeNode parent; // papa - - /** default # of children. Used for tree creation optimization only */ - int nChildren = 8; - - MetadataTreeNode[] children; // of cause - + private static final int DEFAULT_CHILDREN_COUNT = 8; + + /** + * this node's artifact MD + */ + ArtifactMetadata md; + + /** + * fail resolution if it could not be found? + */ + boolean optional = false; + + /** + * parent node + */ + MetadataTreeNode parent; + + /** + * query node - the one that originated this actual node + */ + ArtifactMetadata query; + + /** + * queries - one per POM dependency + */ + List<ArtifactMetadata> queries; + + /** + * actual found versions + */ + List<MetadataTreeNode> children; //------------------------------------------------------------------------ public int countNodes() { return countNodes(this); } //------------------------------------------------------------------------ - public int countNodes( MetadataTreeNode node ) + public static int countNodes( MetadataTreeNode node ) { int res = 1; - if( children != null && children.length > 0) + if( node.children != null && node.children.size() > 0) { - for( MetadataTreeNode child : children ) + for( MetadataTreeNode child : node.children ) { res += countNodes( child ); } @@ -40,25 +65,20 @@ return res; } - //------------------------------------------------------------------------ - public int getNChildren() - { - return nChildren; - } - //------------------------------------------------------------------------ - public void setNChildren(int children) - { - nChildren = children; - } //------------------------------------------------------------------------ public MetadataTreeNode() { } //------------------------------------------------------------------------ - public MetadataTreeNode( ArtifactMetadata md, + /** + * pointers to parent and query are a must. + */ + public MetadataTreeNode( ArtifactMetadata md, MetadataTreeNode parent, + ArtifactMetadata query, boolean resolved, - ArtifactScopeEnum scope ) + ArtifactScopeEnum scope + ) { if ( md != null ) { @@ -68,49 +88,63 @@ this.md = md; this.parent = parent; - } - //------------------------------------------------------------------------ - public MetadataTreeNode( Artifact af, - MetadataTreeNode parent, - boolean resolved, - ArtifactScopeEnum scope - ) - { - this( new ArtifactMetadata( af ), parent, resolved, scope ); - } - //------------------------------------------------------------------------ - public void addChild( int index, MetadataTreeNode kid ) - { - if ( kid == null ) - { - return; - } + this.query = query; + } + //------------------------------------------------------------------------ + public MetadataTreeNode( ArtifactMetadata md, MetadataTreeNode parent, ArtifactMetadata query ) + { + this( md, parent, query, true, ArtifactScopeEnum.compile ); + } + //------------------------------------------------------------------------ + /** + * dependencies are ordered in the POM - they should be added in the POM order + */ + public MetadataTreeNode addChild( MetadataTreeNode kid ) + { + if ( kid == null ) + { + return this; + } - if( children == null ) - children = new MetadataTreeNode[nChildren]; - - children[index % nChildren] = kid; - } + if( children == null ) + { + children = new ArrayList<MetadataTreeNode>( DEFAULT_CHILDREN_COUNT ); + } + + kid.setParent( this ); + children.add( kid ); + + return this; + } + //------------------------------------------------------------------------ + /** + * dependencies are ordered in the POM - they should be added in the POM order + */ + public MetadataTreeNode addQuery( ArtifactMetadata query ) + { + if ( query == null ) + { + return this; + } + + if( queries == null ) + { + queries = new ArrayList<ArtifactMetadata>( DEFAULT_CHILDREN_COUNT ); + } + + queries.add( query ); + + return this; + } //------------------------------------------------------------------ @Override public String toString() { - return md == null ? "no metadata" : md.toString(); - } - //------------------------------------------------------------------ - public String graphHash() - throws MetadataResolutionException - { - if ( md == null ) - { - throw new MetadataResolutionException( "treenode without metadata, parent: " - + ( parent == null ? "null" : parent.toString() ) - ); - } - - return md.groupId + ":" + md.artifactId; + return md == null + ? "no metadata, parent " + ( parent == null ? "null" + : parent.toString() ) : md.toString() + ; } - //------------------------------------------------------------------------ public boolean hasChildren() { @@ -137,14 +171,39 @@ this.parent = parent; } - public MetadataTreeNode[] getChildren() + public List<MetadataTreeNode> getChildren() { return children; } - public void setChildren( MetadataTreeNode[] children ) + public boolean isOptional() + { + return optional; + } + + public void setOptional( boolean optional ) + { + this.optional = optional; + } + public ArtifactMetadata getQuery() + { + return query; + } + public void setQuery(ArtifactMetadata query) + { + this.query = query; + } + public List<ArtifactMetadata> getQueries() + { + return queries; + } + public void setQueries(List<ArtifactMetadata> queries) + { + this.queries = queries; + } + public void setChildren(List<MetadataTreeNode> children) { - this.children = children; + this.children = children; } //------------------------------------------------------------------------ //------------------------------------------------------------------------ Modified: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/DefaultSatSolver.java URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/DefaultSatSolver.java?rev=667301&r1=667300&r2=667301&view=diff ============================================================================== --- maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/DefaultSatSolver.java (original) +++ maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/DefaultSatSolver.java Thu Jun 12 17:12:46 2008 @@ -2,14 +2,19 @@ import java.math.BigInteger; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.apache.maven.mercury.metadata.ArtifactMetadata; import org.apache.maven.mercury.metadata.MetadataTreeNode; import org.sat4j.pb.IPBSolver; import org.sat4j.pb.SolverFactory; import org.sat4j.specs.ContradictionException; +import org.sat4j.specs.IVec; +import org.sat4j.specs.IVecInt; import org.sat4j.specs.TimeoutException; +import org.w3c.dom.NodeList; /** * @author <a href="[EMAIL PROTECTED]">Oleg Gusakov</a> @@ -20,11 +25,6 @@ protected SatContext context; protected IPBSolver solver = SolverFactory.newEclipseP2(); //----------------------------------------------------------------------- - //----------------------------------------------------------------------- - // x ⨠y = ¬(¬xâ§Â¬y) - // x ⨠y ⨠z = ¬(¬x ⧠¬(y ⨠z)) = ¬(¬x ⧠¬(¬(¬yâ§Â¬z))) = ¬(¬x ⧠¬y ⧠¬z ) - // x â§ y => x+y >= 2, ¬x ⧠¬y => x+y < 1 - //----------------------------------------------------------------------- public static SatSolver create( MetadataTreeNode tree ) throws SatException { @@ -39,235 +39,183 @@ int nNodes = tree.countNodes(); context = new SatContext( nNodes ); - setPivots( tree ); - setOthers( tree ); - solver.newVar( context.varCount ); + + try + { + addNode( tree ); + } + catch (ContradictionException e) + { + throw new SatException(e); + } } //----------------------------------------------------------------------- - // test only factory & constructor - protected static SatSolver create( int nVars ) - throws SatException - { - return new DefaultSatSolver( nVars ); - } - - protected DefaultSatSolver( int nVars ) - throws SatException + private final void addPB( IVecInt lits, IVec<BigInteger> coeff, boolean ge, BigInteger cardinality ) + throws ContradictionException { - context = new SatContext( nVars ); - solver.newVar( nVars ); + solver.addPseudoBoolean( lits, coeff, ge, cardinality ); + + System.out.print("PB: "); + for( int i=0; i<lits.size(); i++ ) + System.out.print( " "+coeff.get(i)+" x"+lits.get(i) ); + System.out.println(" "+( ge ? ">=" : "<")+" "+cardinality ); } //----------------------------------------------------------------------- - private final void setPivots( MetadataTreeNode tree ) + private Map<ArtifactMetadata, List<MetadataTreeNode>> processChildren( + List<ArtifactMetadata> queries + , List<MetadataTreeNode> children + ) throws SatException { - if( tree == null ) - return; - -// TODO implement -if(true) throw new SatException("Not implemented yet"); - - context.addWeak( tree.getMd() ); - if( tree.getChildren() != null ) - for( MetadataTreeNode child : tree.getChildren() ) + HashMap<ArtifactMetadata, List<MetadataTreeNode>> res = new HashMap<ArtifactMetadata, List<MetadataTreeNode>>( queries.size() ); + for( ArtifactMetadata q : queries ) + { + 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); + + List<MetadataTreeNode> bucket = new ArrayList<MetadataTreeNode>(4); + String queryGA = q.getGA(); + + for( MetadataTreeNode tn : children ) { - setPivots( child ); + 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 setOthers( MetadataTreeNode tree ) - throws SatException + private void addNode( MetadataTreeNode node ) + throws ContradictionException, SatException { - if( tree == null ) + if( node == null ) return; - context.addStrong( tree.getMd() ); - if( tree.getChildren() != null ) - for( MetadataTreeNode child : tree.getChildren() ) + if( node.getMd() == null ) + throw new SatException("found a node without metadata"); + + SatVar nodeLit = context.findOrAdd( node.getMd() ); + + if( node.getParent() == null ) { - setOthers( child ); + addPB( SatHelper.getSmallOnes( nodeLit.getLiteral() ) + , SatHelper.getBigOnes(1,false) + , true, BigInteger.valueOf(1) + ); } - } - //----------------------------------------------------------------------- - private List<ArtifactMetadata> groupCommonHear( List<List<ArtifactMetadata>> orGroup ) - throws SatException - { - if( orGroup == null || orGroup.size() < 1 ) - throw new SatException("cannot scan empty group for common head"); + + if( ! node.hasChildren() ) + return; - int groupSize = orGroup.size(); - List<ArtifactMetadata> res = new ArrayList<ArtifactMetadata>( orGroup.get(0) ); + Map<ArtifactMetadata,List<MetadataTreeNode>> kids = processChildren( node.getQueries(), node.getChildren() ); - // one member? - done - if( groupSize == 1 ) - return res; + // leaf node + if( kids == null ) + return; - int index = 0; - - for( List<ArtifactMetadata> branch : orGroup ) + for( Map.Entry<ArtifactMetadata,List<MetadataTreeNode>> kid : kids.entrySet() ) { - if( index++ == 0 ) - continue; + ArtifactMetadata query = kid.getKey(); + List<MetadataTreeNode> range = kid.getValue(); - for( ArtifactMetadata md : branch ) + if( range.size() > 1 ) { - int len = res.size(); + int [] literals = addRange( range, query.isOptional() ); + int litCount = literals.length; - for( int i=0; i<len; i++ ) + addPB( SatHelper.getSmallOnes( SatHelper.toIntArray( nodeLit.getLiteral(), literals ) ) + , SatHelper.getBigOnes(-1,litCount,false) + , true, BigInteger.ZERO + ); + for( MetadataTreeNode tn : range ) { - ArtifactMetadata hmd = res.get(i); - - if( hmd.sameGAV(md) ) - continue; - - // remove the rest - for( int j=i; j<len; j++ ) - res.remove(i); - - break; + addNode( tn ); } } + else + { + MetadataTreeNode child = range.get(0); + SatVar kidLit = context.findOrAdd( child.getMd() ); + + addPB( SatHelper.getSmallOnes( new int [] { nodeLit.getLiteral(), kidLit.getLiteral() } ) + , SatHelper.getBigOnes( -1, 1 ) + , true, BigInteger.ZERO + ); + addNode( child ); + } + } - - return res; } //----------------------------------------------------------------------- - private int calcWeekness( List<ArtifactMetadata> branch, int currentMin ) + private int [] addRange( List<MetadataTreeNode> range, boolean optional ) + throws ContradictionException, SatException { - int res = 0; + SatVar literal; - for( ArtifactMetadata md : branch ) - { - SatVar v = context.find(md); - - if( v.isWeak() ) - ++res; - } + int [] literals = new int[ range.size() ]; - return res < currentMin ? res : currentMin; - } - //----------------------------------------------------------------------- - public SatConstraint addOrGroup( List<List<ArtifactMetadata>> orGroup ) - throws SatException - { - if( orGroup == null || orGroup.size() < 1 ) - throw new SatException("cannot process empty OR group"); + int count = 0; - try + for( MetadataTreeNode tn : range ) { - SatConstraint constraint = null; - int groupSize = orGroup.size(); - int maxLen = 0; - int minWeekness = Integer.MAX_VALUE; - - for( List<ArtifactMetadata> branch : orGroup ) - { - if( constraint == null ) - constraint = new SatConstraint( branch, context, SatContext.STRONG_VAR ); - else - constraint.addOrGroupMember( branch, context ); - - if( maxLen < branch.size() ) - maxLen = branch.size(); - - minWeekness = calcWeekness(branch, minWeekness ); - } - - // second pass - adjust each branch with strong variable up to the max length - for( List<ArtifactMetadata> branch : orGroup ) - { - constraint.adjust( branch, maxLen, minWeekness, context ); - } - - // 3rd pass - generate branch structure implications - for( List<ArtifactMetadata> branch : orGroup ) - { - int blen = branch.size(); - if( blen == 1 ) - break; - - SatVar currLit = context.find( branch.get(0) ); - SatVar nextLit = null; - - for( int i=1; i < blen; i++ ) - { - nextLit = context.find( branch.get(i) ); -System.out.println(nextLit._md+" -> "+currLit._md + " : -x"+ nextLit._no+" +x"+currLit._no+" >= -1"); - // generate implication nextLit -> currLit - solver.addPseudoBoolean( - SatHelper.getSmallOnes( nextLit._no, currLit._no ) - , SatHelper.getBigOnes( -1, 1 ) - , true - , new BigInteger("0") - ); - solver.addPseudoBoolean( - SatHelper.getSmallOnes( nextLit._no, currLit._no ) - , SatHelper.getBigOnes( -1, 1 ) - , false - , new BigInteger("1") - ); - currLit = nextLit; - } - } - - constraint.finalAdjust( orGroup.get(0), groupSize, minWeekness, context ); - - if( constraint != null ) - { - constraint.cardinality = groupSize * maxLen; -System.out.println("Contraint is "+constraint.toString() ); - SatClause clause = constraint.getClause(); - solver.addPseudoBoolean( - SatHelper.getSmallOnes( clause._vars ) - , SatHelper.getBigOnes( clause._coeff ) - , true - , new BigInteger(""+constraint.cardinality) - ); - } - - return constraint; + literal = context.findOrAdd( tn.getMd() ); + literals[count++] = literal.getLiteral(); } - catch (ContradictionException e) + + if( optional ) // Sxi >= 0 { - throw new SatException( e ); + addPB( SatHelper.getSmallOnes( literals ) + , SatHelper.getBigOnes( count, false ) + , true, BigInteger.ZERO + ); } - } - //----------------------------------------------------------------------- - public SatConstraint addPivot( List<ArtifactMetadata> pivot ) - throws SatException - { -System.out.println("Pivot: " + pivot ); - SatConstraint constraint = new SatConstraint( pivot, context, SatContext.WEAK_VAR ); - - try + else // Sxi = 1 { - int [] vars1 = constraint.getVarray(); - int varCount1 = vars1.length; - - solver.addPseudoBoolean( - SatHelper.getSmallOnes( vars1 ) - , SatHelper.getBigOnes( varCount1 ) + addPB( + SatHelper.getSmallOnes( literals ) + , SatHelper.getBigOnes( count, false ) , true , new BigInteger("1") ); - int [] vars2 = constraint.getVarray(); - int varCount2 = vars2.length; - - solver.addPseudoBoolean( - SatHelper.getSmallOnes( vars2 ) - , SatHelper.getBigOnes( varCount2, true ) + addPB( + SatHelper.getSmallOnes( literals ) + , SatHelper.getBigOnes( count, true ) , true , new BigInteger("-1") ); } - catch (ContradictionException e) - { - throw new SatException( e ); - } - return constraint; + return literals; + } + //----------------------------------------------------------------------- + // test only factory & constructor + protected static SatSolver create( int nVars ) + throws SatException + { + return new DefaultSatSolver( nVars ); + } + + protected DefaultSatSolver( int nVars ) + throws SatException + { + context = new SatContext( nVars ); + solver.newVar( nVars ); } //----------------------------------------------------------------------- public List<ArtifactMetadata> solve() @@ -282,7 +230,7 @@ res = new ArrayList<ArtifactMetadata>( context.varCount ); for( SatVar v : context.variables ) { - boolean yes = solver.model( v.getNo() ); + boolean yes = solver.model( v.getLiteral() ); if( yes ) res.add( v.getMd() ); } Modified: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/SatContext.java URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/SatContext.java?rev=667301&r1=667300&r2=667301&view=diff ============================================================================== --- maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/SatContext.java (original) +++ maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/SatContext.java Thu Jun 12 17:12:46 2008 @@ -13,98 +13,38 @@ */ class SatContext { - public static final boolean STRONG_VAR = false; - public static final boolean WEAK_VAR = true; - List<SatVar> variables; int varCount = 0; - boolean pivotsFinished = false; //----------------------------------------------------------------------- - public SatContext(int estimatedTreeSize ) + public SatContext( int estimatedTreeSize ) { variables = new ArrayList<SatVar>( estimatedTreeSize ); } //----------------------------------------------------------------------- - public SatVar addWeak( ArtifactMetadata md ) + public SatVar findOrAdd( ArtifactMetadata md ) throws SatException { - if( pivotsFinished ) - throw new SatException( "cannot mix Pivots and OR Groups. Pivots are always first." ); - if( md == null ) throw new SatException( "cannot create a literal out of a null metadata: "+md ); for( SatVar var : variables ) { { - if( ! var._optional ) - throw new SatException( "Literal x"+var._no+" ia already marked as strong. Cannot add it as weak." ); - if( var._md.sameGAV(md) ) + { +System.out.println(md+" -> x"+var._literal); return var; + } } } - SatVar var = new SatVar( md, ++varCount, WEAK_VAR ); + SatVar var = new SatVar( md, ++varCount ); variables.add( var ); +System.out.println(md+" -> x"+var._literal); return var; } //----------------------------------------------------------------------- - public SatVar addStrong( ArtifactMetadata md ) - throws SatException - { - - if( md == null ) - throw new SatException( "cannot create a literal out of a null metadata: "+md ); - - // force-finish pivots on the first non-pivot - pivotsFinished = true; - - for( SatVar var : variables ) - { - if( var.compareTo(md) == 0 ) - { - if( var._optional ) - throw new SatException( "Literal x"+var._no+" ia already marked as weak. Cannot add it as strong." ); - - if( var._md.sameGAV(md) ) - return var; - } - } - - SatVar var = new SatVar( md, ++varCount, STRONG_VAR ); - variables.add( var ); - - return var; - } - //----------------------------------------------------------------------- - private SatVar findOrAdd( ArtifactMetadata md, boolean optional ) - throws SatException - { - for( SatVar var : variables ) - { - if( var.compareTo(md) == 0 ) - return var; - } - - SatVar var = new SatVar( md, ++varCount, optional ); - variables.add( var ); - - return var; - } - //----------------------------------------------------------------------- - public SatVar find( ArtifactMetadata md ) - { - for( SatVar var : variables ) - { - if( var.compareTo(md) == 0 ) - return var; - } - - return null; - } - //----------------------------------------------------------------------- @Override public String toString() { @@ -115,7 +55,7 @@ for( SatVar var : variables ) { - sb.append(comma+" "+(var.isWeak()?'w':'s')+var._no+"="+var._md.toString() ); + sb.append(comma+" x"+var._literal+"="+var._md.toString() ); comma = ','; } return sb.toString()+']'; Modified: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/SatHelper.java URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/SatHelper.java?rev=667301&r1=667300&r2=667301&view=diff ============================================================================== --- maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/SatHelper.java (original) +++ maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/SatHelper.java Thu Jun 12 17:12:46 2008 @@ -12,6 +12,8 @@ import org.sat4j.specs.IVec; import org.sat4j.specs.IVecInt; +import com.sun.org.apache.bcel.internal.generic.GETSTATIC; + public class SatHelper { //----------------------------------------------------------------------- @@ -31,6 +33,23 @@ return new ReadOnlyVecInt(res); } //----------------------------------------------------------------------- + public static final IVecInt getSmallOnes( int first, int second ) + { + return getSmallOnes( new int [] {first, second} ); + } + //----------------------------------------------------------------------- + public static int [] toIntArray( int first, int... ints ) + { + int [] lits = new int[ ints.length+1 ]; + lits[0] = first; + int ptr = 1; + + for( int i : ints ) + lits[ptr++] = i; + + return lits; + } + //----------------------------------------------------------------------- private static final IVec<BigInteger> toVec( BigInteger... bis ) { return new ReadOnlyVec<BigInteger>( new Vec<BigInteger>( bis ) ); @@ -41,16 +60,11 @@ BigInteger [] res = new BigInteger[ ones.length ]; for( int i=0; i<ones.length; i++ ) - res[ i ] = new BigInteger(""+ones[i]); + res[ i ] = BigInteger.valueOf( ones[i] ); return toVec( res ); } //----------------------------------------------------------------------- - public static final IVec<BigInteger> getBigOnes( int nOnes ) - { - return getBigOnes( nOnes, false ); - } - //----------------------------------------------------------------------- public static final IVec<BigInteger> getBigOnes( int nOnes, boolean negate ) { BigInteger [] res = new BigInteger[ nOnes ]; @@ -62,6 +76,21 @@ return toVec(res); } //----------------------------------------------------------------------- + public static final IVec<BigInteger> getBigOnes( int first, int nOnes, boolean negateOnes ) + { + int len = nOnes + 1; + + BigInteger [] res = new BigInteger[ len ]; + res[ 0 ] = BigInteger.valueOf(first); + + BigInteger bi = negateOnes ? BigInteger.ONE.negate() : BigInteger.ONE; + + for( int i=0; i<nOnes; i++ ) + res[i+1] = bi; + + return toVec(res); + } + //----------------------------------------------------------------------- public static final void show( int... ones ) { for( int i=0; i<ones.length; i++ ) Modified: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/SatSolver.java URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/SatSolver.java?rev=667301&r1=667300&r2=667301&view=diff ============================================================================== --- maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/SatSolver.java (original) +++ maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/SatSolver.java Thu Jun 12 17:12:46 2008 @@ -11,12 +11,6 @@ { public static final int DEFAULT_TREE_SIZE = 128; //nodes - public SatConstraint addOrGroup( List<List<ArtifactMetadata>> orGroup ) - throws SatException; - - public SatConstraint addPivot( List<ArtifactMetadata> pivot ) - throws SatException; - public List<ArtifactMetadata> solve() throws SatException; } Modified: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/SatVar.java URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/SatVar.java?rev=667301&r1=667300&r2=667301&view=diff ============================================================================== --- maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/SatVar.java (original) +++ maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/sat/SatVar.java Thu Jun 12 17:12:46 2008 @@ -9,10 +9,10 @@ implements Comparable<ArtifactMetadata> { ArtifactMetadata _md; - int _no; + int _literal; boolean _optional; //--------------------------------------------------------------------- - public SatVar( ArtifactMetadata md, int var, boolean optional ) + public SatVar( ArtifactMetadata md, int literal ) throws SatException { if( md == null @@ -23,8 +23,7 @@ throw new SatException("Cannot create SatVar from a null Metadata: "+md); this._md = md; - this._no = var; - this._optional = optional; + this._literal = literal; } //--------------------------------------------------------------------- public ArtifactMetadata getMd() @@ -35,13 +34,13 @@ { this._md = md; } - public int getNo() + public int getLiteral() { - return _no; + return _literal; } public void setNo(int var) { - this._no = var; + this._literal = var; } public boolean isWeak() Modified: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/transform/ClasspathContainer.java URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/transform/ClasspathContainer.java?rev=667301&r1=667300&r2=667301&view=diff ============================================================================== --- maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/transform/ClasspathContainer.java (original) +++ maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/metadata/transform/ClasspathContainer.java Thu Jun 12 17:12:46 2008 @@ -72,7 +72,8 @@ for ( ArtifactMetadata md : classpath ) { - node = new MetadataTreeNode( md, parent, md.isResolved(), md.getArtifactScope() ); + // TODO Oleg: is null for query good here ?? + node = new MetadataTreeNode( md, parent, null, md.isResolved(), md.getArtifactScope() ); if ( tree == null ) { tree = node; @@ -80,8 +81,7 @@ if ( parent != null ) { - parent.setNChildren( 1 ); - parent.addChild( 0, node ); + parent.addChild( node ); } parent = node; Modified: maven/sandbox/trunk/mercury/src/test/java/org/apache/maven/mercury/metadata/sat/DefaultSatSolverTest.java URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/src/test/java/org/apache/maven/mercury/metadata/sat/DefaultSatSolverTest.java?rev=667301&r1=667300&r2=667301&view=diff ============================================================================== --- maven/sandbox/trunk/mercury/src/test/java/org/apache/maven/mercury/metadata/sat/DefaultSatSolverTest.java (original) +++ maven/sandbox/trunk/mercury/src/test/java/org/apache/maven/mercury/metadata/sat/DefaultSatSolverTest.java Thu Jun 12 17:12:46 2008 @@ -3,7 +3,9 @@ import java.util.ArrayList; import java.util.List; +import org.apache.maven.mercury.ArtifactScopeEnum; import org.apache.maven.mercury.metadata.ArtifactMetadata; +import org.apache.maven.mercury.metadata.MetadataTreeNode; import junit.framework.TestCase; @@ -15,107 +17,99 @@ { DefaultSatSolver ss; String title; - List< List<ArtifactMetadata> > or; - SatConstraint constraint; + + MetadataTreeNode tree; + + ArtifactMetadata a1 = new ArtifactMetadata("t:a:1"); + ArtifactMetadata b1 = new ArtifactMetadata("t:b:1"); + ArtifactMetadata b2 = new ArtifactMetadata("t:b:2"); + ArtifactMetadata b3 = new ArtifactMetadata("t:b:3"); + ArtifactMetadata c1 = new ArtifactMetadata("t:c:1"); + ArtifactMetadata c2 = new ArtifactMetadata("t:c:2"); //---------------------------------------------------------------------- protected void setUp() throws Exception { super.setUp(); - - or = new ArrayList< List<ArtifactMetadata> >(8); - } //---------------------------------------------------------------------- public void testContext() throws SatException { + title = "context test"; + System.out.println("\n\n==========================\n"+title+"\n"); + ss = (DefaultSatSolver) DefaultSatSolver.create(3); - - ss.addPivot(SatHelper.createList("t:b:1","t:b:2" )); + ss.context.findOrAdd( b1 ); + ss.context.findOrAdd( b2 ); assert ss.context != null : "created solver has a null context"; assert ss.context.varCount == 2 : "expected 2 variables in the context, but found "+ss.context.varCount; - or = new ArrayList< List<ArtifactMetadata> >(1); - - or.add( SatHelper.createList("t:a:1","t:b:1" ) ); - ss.addOrGroup(or); - + ss.context.findOrAdd( a1 ); assert ss.context.varCount == 3 : "expected 3 variables in the context, but found "+ss.context.varCount; - or = new ArrayList< List<ArtifactMetadata> >(1); - or.add( SatHelper.createList("t:a:1","t:b:2" ) ); - ss.addOrGroup(or); - + ss.context.findOrAdd( b1 ); assert ss.context.varCount == 3 : "expected 3 variables in the context, but found "+ss.context.varCount; } //---------------------------------------------------------------------- - public void testSimplestResolution() + // + // a1 + // and (b1 or b2 or b3) + // and ((c1 and b1) or (c2 and (b2 or b3)) + // + //---------------------------------------------------------------------- + public void testClassictResolution() throws SatException { title = "simplest 3-node tree"; - System.out.println("\n"+title+"\n"); - - ss = (DefaultSatSolver) DefaultSatSolver.create(3); - - constraint = ss.addPivot( SatHelper.createList("t:b:1","t:b:2") ); - System.out.println("Pivot: "+constraint.toString() ); - - or.add( SatHelper.createList("t:a:1","t:b:1") ); - or.add( SatHelper.createList("t:a:1","t:b:2") ); - constraint = ss.addOrGroup(or); - System.out.println("Constraint: "+constraint.toString() ); + System.out.println("\n\n==========================\n"+title+"\n"); - System.out.println("\nContext: "+ss.context.toString()+"\n" ); + MetadataTreeNode na1 = new MetadataTreeNode( a1, null, null ) + .addQuery(b1) + .addQuery(c1) + ; + + MetadataTreeNode nb1 = new MetadataTreeNode( b1, na1, b1 ); + MetadataTreeNode nb2 = new MetadataTreeNode( b2, na1, b1 ); + MetadataTreeNode nb3 = new MetadataTreeNode( b3, na1, b1 ); + + MetadataTreeNode nc1 = new MetadataTreeNode( c1, na1, c1 ) + .addQuery(b1) + ; + MetadataTreeNode nc2 = new MetadataTreeNode( c2, na1, c1 ) + .addQuery(b1) + ; + + na1 + .addChild(nb1) + .addChild(nb2) + .addChild(nb3) + .addChild(nc1) + .addChild(nc2) + ; + + nc1 + .addChild(nb1) + ; + + nc2 + .addChild(nb2) + .addChild(nb3) + ; - List<ArtifactMetadata> res = ss.solve(); -System.out.print("model: " ); -int m[] = ss.solver.model(); -for( int i=0; i<m.length; i++ ) - System.out.print(" "+m[i]); -System.out.println(""); - - assert res != null : "Failed to solve "+title; - - System.out.print("Result:"); - for( ArtifactMetadata md : res ) - { - System.out.print(" "+md); - } - System.out.println(""); + ss = (DefaultSatSolver) DefaultSatSolver.create(na1); - assert res.size() == 2 : "result contains "+res.size()+" artifacts instead of 2"; - } - //---------------------------------------------------------------------- - public void testSimpleResolution() - throws SatException - { - title = "simple 4-node tree"; - System.out.println("\n"+title+"\n"); - - ss = (DefaultSatSolver) DefaultSatSolver.create(4); - - constraint = ss.addPivot( SatHelper.createList("t:b:1","t:b:2","t:b:3") ); - System.out.println("Pivot: "+constraint.toString() ); - - or.add( SatHelper.createList("t:a:1","t:b:1") ); - or.add( SatHelper.createList("t:a:1","t:b:2") ); - or.add( SatHelper.createList("t:a:1","t:b:3") ); - constraint = ss.addOrGroup(or); - System.out.println("Constraint: "+constraint.toString() ); + List<ArtifactMetadata> res = ss.solve(); - System.out.println("\nContext: "+ss.context.toString()+"\n" ); + int m[] = ss.solver.model(); - List<ArtifactMetadata> res = ss.solve(); -System.out.print("model: " ); -int m[] = ss.solver.model(); -for( int i=0; i<m.length; i++ ) - System.out.print(" "+m[i]); -System.out.println(""); + System.out.print("model: " ); + for( int i=0; i<m.length; i++ ) + System.out.print(" "+m[i]); + System.out.println(""); - assert res != null : "Failed to solve "+title; System.out.print("Result:"); @@ -125,54 +119,11 @@ } System.out.println(""); - assert res.size() == 2 : "result contains "+res.size()+" artifacts instead of 2"; - } - //---------------------------------------------------------------------- - public void testClassicResolution() - throws SatException - { - title = "Classical ranges tree"; - System.out.println("\n"+title+"\n"); - - ss = (DefaultSatSolver) DefaultSatSolver.create(6); - - constraint = ss.addPivot( SatHelper.createList("t:b:1","t:b:2","t:b:3") ); - System.out.println("Pivot: "+constraint.toString() ); - - constraint = ss.addPivot( SatHelper.createList("t:c:1","t:c:2") ); - System.out.println("Pivot: "+constraint.toString() ); - - or.add( SatHelper.createList("t:a:1","t:b:1") ); - or.add( SatHelper.createList("t:a:1","t:b:2") ); - or.add( SatHelper.createList("t:a:1","t:b:3") ); - constraint = ss.addOrGroup(or); - System.out.println("Constraint: "+constraint.toString() ); - - or.clear(); - - or.add( SatHelper.createList("t:a:1","t:c:1","t:b:1") ); - or.add( SatHelper.createList("t:a:1","t:c:2","t:b:2") ); - or.add( SatHelper.createList("t:a:1","t:c:2","t:b:3") ); - constraint = ss.addOrGroup(or); - System.out.println("Constraint: "+constraint.toString() ); - - System.out.println( "Context: "+ss.context.toString() ); - - List<ArtifactMetadata> res = ss.solve(); - if(res==null) - System.out.println("\n"+title+" unsatified"); - - assert res != null : "Failed to solve "+title; -// assert res.size() == 2 : "result contains "+res.size()+" artifacts instead of 2"; - - System.out.println("\n"+title+" result:"); - for( ArtifactMetadata md : res ) - { - System.out.print(" "+md); - } + assert res.size() == 3 : "result contains "+res.size()+" artifacts instead of 3"; + assert res.contains(a1) : "result does not contain "+a1; } //---------------------------------------------------------------------- - public void testT() + public void ntestT() { for( int i=0; i<2; i++) for( int j=0; j<2; j++)