use of org.logicng.cardinalityconstraints.CCIncrementalData in project LogicNG by logic-ng.
the class QuineMcCluskeyAlgorithm method minimize.
/**
* Performs the minimization via incremental cardinality constraints.
* @param satSolver the SAT solver
* @param var2Term a mapping from selector variable to prime implicant
* @param f the formula factory
* @return a minimal set of prime implicants to cover all minterms
*/
static List<Term> minimize(final SATSolver satSolver, final LinkedHashMap<Variable, Term> var2Term, final FormulaFactory f) {
final Assignment initialModel = satSolver.model();
List<Variable> currentTermVars = computeCurrentTermVars(initialModel, var2Term.keySet());
if (currentTermVars.size() == 2) {
satSolver.add(f.amo(var2Term.keySet()));
if (satSolver.sat() == Tristate.TRUE) {
currentTermVars = computeCurrentTermVars(satSolver.model(), var2Term.keySet());
}
} else {
final Formula cc = f.cc(CType.LE, currentTermVars.size() - 1, var2Term.keySet());
assert cc instanceof CardinalityConstraint;
final CCIncrementalData incData = satSolver.addIncrementalCC((CardinalityConstraint) cc);
while (satSolver.sat() == Tristate.TRUE) {
currentTermVars = computeCurrentTermVars(satSolver.model(), var2Term.keySet());
incData.newUpperBoundForSolver(currentTermVars.size() - 1);
}
}
return computeTerms(currentTermVars, var2Term);
}
use of org.logicng.cardinalityconstraints.CCIncrementalData in project LogicNG by logic-ng.
the class OptimizationFunction method maximize.
private Assignment maximize(final MiniSat solver) {
start(this.handler);
final FormulaFactory f = solver.factory();
LNGBooleanVector internalModel;
final Map<Variable, Literal> selectorMap = new TreeMap<>();
for (final Literal lit : this.literals) {
final Variable selVar = f.variable(SEL_PREFIX + selectorMap.size());
selectorMap.put(selVar, lit);
}
final Set<Variable> selectors = selectorMap.keySet();
if (this.maximize) {
selectorMap.forEach((selVar, lit) -> solver.add(f.or(selVar.negate(), lit)));
selectorMap.forEach((selVar, lit) -> solver.add(f.or(lit.negate(), selVar)));
} else {
selectorMap.forEach((selVar, lit) -> solver.add(f.or(selVar.negate(), lit.negate())));
selectorMap.forEach((selVar, lit) -> solver.add(f.or(lit, selVar)));
}
Tristate sat = solver.sat(satHandler(handler));
if (sat != Tristate.TRUE || aborted(handler)) {
return null;
}
internalModel = solver.underlyingSolver().model();
Assignment currentModel = solver.model(selectors);
int currentBound = currentModel.positiveVariables().size();
if (currentBound == 0) {
solver.add(f.cc(CType.GE, 1, selectors));
sat = solver.sat(satHandler(handler));
if (aborted(handler)) {
return null;
} else if (sat == Tristate.FALSE) {
return mkResultModel(solver, internalModel);
} else {
internalModel = solver.underlyingSolver().model();
currentModel = solver.model(selectors);
currentBound = currentModel.positiveVariables().size();
}
} else if (currentBound == selectors.size()) {
return mkResultModel(solver, internalModel);
}
final Formula cc = f.cc(CType.GE, currentBound + 1, selectors);
assert cc instanceof CardinalityConstraint;
final CCIncrementalData incrementalData = solver.addIncrementalCC((CardinalityConstraint) cc);
sat = solver.sat(satHandler(handler));
if (aborted(handler)) {
return null;
}
while (sat == Tristate.TRUE) {
final LNGBooleanVector modelCopy = new LNGBooleanVector(solver.underlyingSolver().model());
if (this.handler != null && !this.handler.foundBetterBound(() -> mkResultModel(solver, modelCopy))) {
return null;
}
internalModel = modelCopy;
currentModel = solver.model(selectors);
currentBound = currentModel.positiveVariables().size();
if (currentBound == selectors.size()) {
return mkResultModel(solver, internalModel);
}
incrementalData.newLowerBoundForSolver(currentBound + 1);
sat = solver.sat(satHandler(handler));
if (aborted(handler)) {
return null;
}
}
return mkResultModel(solver, internalModel);
}
Aggregations