blob: 54626eb6a85b6b130d0db3a626de83296029e76c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 Daniel Le Berre and others. All rights reserved. This
* program and the accompanying materials are made available under the terms of
* the Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors: Daniel Le Berre - initial API and implementation
******************************************************************************/
package org.eclipse.equinox.p2.cudf.solver;
import java.math.BigInteger;
import java.util.*;
import org.eclipse.equinox.p2.cudf.metadata.InstallableUnit;
import org.eclipse.equinox.p2.cudf.query.QueryableArray;
import org.sat4j.pb.tools.DependencyHelper;
import org.sat4j.pb.tools.WeightedObject;
import org.sat4j.specs.ContradictionException;
public abstract class OptimizationFunction {
protected Map slice;
protected Map noopVariables;
protected QueryableArray picker;
protected DependencyHelper dependencyHelper;
protected List removalVariables = new ArrayList();
protected List changeVariables = new ArrayList();
protected List nouptodateVariables = new ArrayList();
protected List newVariables = new ArrayList();
protected List optionalityVariables;
public abstract List createOptimizationFunction(InstallableUnit metaIu);
public abstract void printSolutionValue();
protected void removed(List weightedObjects, BigInteger weight, InstallableUnit metaIu) {
Set s = slice.entrySet();
for (Iterator iterator = s.iterator(); iterator.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
if (entry.getKey() == metaIu.getId())
continue;
Collection versions = ((HashMap) entry.getValue()).values();
boolean installed = false;
for (Iterator iterator2 = versions.iterator(); iterator2.hasNext();) {
InstallableUnit iuv = (InstallableUnit) iterator2.next();
installed = installed || iuv.isInstalled();
}
if (installed) {
try {
Projector.AbstractVariable abs = new Projector.AbstractVariable(entry.getKey().toString());
removalVariables.add(abs);
// a => not iuv1 and ... and not iuvn
for (Iterator iterator2 = versions.iterator(); iterator2.hasNext();) {
dependencyHelper.implication(new Object[] {abs}).impliesNot(iterator2.next()).named("OPT1");
}
// a <= not iuv1 and ... and not iuvn
Object[] clause = new Object[versions.size() + 1];
versions.toArray(clause);
clause[clause.length - 1] = abs;
dependencyHelper.clause("OPT1", clause);
weightedObjects.add(WeightedObject.newWO(abs, weight));
} catch (ContradictionException e) {
// should not happen
e.printStackTrace();
}
}
}
}
protected void changed(List weightedObjects, BigInteger weight, InstallableUnit metaIu) {
Set s = slice.entrySet();
for (Iterator iterator = s.iterator(); iterator.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
if (entry.getKey() == metaIu.getId())
continue;
Collection versions = ((HashMap) entry.getValue()).values();
List changed = new ArrayList(versions.size());
for (Iterator iterator2 = versions.iterator(); iterator2.hasNext();) {
InstallableUnit iu = (InstallableUnit) iterator2.next();
if (iu.isInstalled()) {
changed.add(dependencyHelper.not(iu));
} else {
changed.add(iu);
}
}
try {
Projector.AbstractVariable abs = new Projector.AbstractVariable(entry.getKey().toString());
changeVariables.add(abs);
// a <= iuv1 or not iuv2 or ... or not iuvn
for (Iterator iterator2 = changed.iterator(); iterator2.hasNext();) {
dependencyHelper.implication(new Object[] {iterator2.next()}).implies(abs).named("OPT3");
}
// a => iuv1 or not iuv2 or ... or not iuvn
Object[] clause = new Object[changed.size()];
changed.toArray(clause);
dependencyHelper.implication(new Object[] {abs}).implies(clause).named("OPT3");
weightedObjects.add(WeightedObject.newWO(abs, weight));
} catch (ContradictionException e) {
// should not happen
e.printStackTrace();
}
}
}
protected void uptodate(List weightedObjects, BigInteger weight, InstallableUnit metaIu) {
Set s = slice.entrySet();
for (Iterator iterator = s.iterator(); iterator.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
if (entry.getKey() == metaIu.getId())
continue;
HashMap versions = (HashMap) entry.getValue();
List toSort = new ArrayList(versions.values());
Collections.sort(toSort, Collections.reverseOrder());
weightedObjects.add(WeightedObject.newWO(toSort.get(0), weight));
}
}
protected void notuptodate(List weightedObjects, BigInteger weight, InstallableUnit metaIu) {
Set s = slice.entrySet();
for (Iterator iterator = s.iterator(); iterator.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
if (entry.getKey() == metaIu.getId())
continue;
HashMap versions = (HashMap) entry.getValue();
List toSort = new ArrayList(versions.values());
Collections.sort(toSort, Collections.reverseOrder());
Projector.AbstractVariable abs = new Projector.AbstractVariable(entry.getKey().toString());
Object notlatest = dependencyHelper.not(toSort.get(0));
try {
dependencyHelper.implication(new Object[] {abs}).implies(notlatest).named("OPT4");
Object[] clause = new Object[toSort.size()];
toSort.toArray(clause);
clause[0] = dependencyHelper.not(abs);
dependencyHelper.clause("OPT4", clause);
for (int i = 1; i < toSort.size(); i++) {
dependencyHelper.implication(new Object[] {notlatest, toSort.get(i)}).implies(abs).named("OPT4");
}
} catch (ContradictionException e) {
// should never happen
e.printStackTrace();
}
weightedObjects.add(WeightedObject.newWO(abs, weight));
nouptodateVariables.add(abs);
}
}
protected void niou(List weightedObjects, BigInteger weight, InstallableUnit metaIu) {
Set s = slice.entrySet();
for (Iterator iterator = s.iterator(); iterator.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
if (entry.getKey() == metaIu.getId())
continue;
Collection versions = ((HashMap) entry.getValue()).values();
boolean installed = false;
for (Iterator iterator2 = versions.iterator(); iterator2.hasNext();) {
InstallableUnit iuv = (InstallableUnit) iterator2.next();
installed = installed || iuv.isInstalled();
}
if (!installed) {
try {
Projector.AbstractVariable abs = new Projector.AbstractVariable(entry.getKey().toString());
newVariables.add(abs);
// a <= iuv1 or ... or iuvn
for (Iterator iterator2 = versions.iterator(); iterator2.hasNext();) {
dependencyHelper.implication(new Object[] {iterator2.next()}).implies(abs).named("OPT2");
}
// a => iuv1 or ... or iuvn
Object[] clause = new Object[versions.size()];
versions.toArray(clause);
dependencyHelper.implication(new Object[] {abs}).implies(clause).named("OPT2");
weightedObjects.add(WeightedObject.newWO(abs, weight));
} catch (ContradictionException e) {
// should not happen
e.printStackTrace();
}
}
}
}
protected void optional(List weightedObjects, BigInteger weight, InstallableUnit metaIu) {
for (Iterator it = optionalityVariables.iterator(); it.hasNext();) {
weightedObjects.add(WeightedObject.newWO(it.next(), weight));
}
}
public abstract String getName();
}