use of org.logicng.solvers.SATSolver in project LogicNG by logic-ng.
the class MinimumPrimeImplicantFunction method apply.
@Override
public SortedSet<Literal> apply(final Formula formula, final boolean cache) {
final Formula nnf = formula.nnf();
final Map<Variable, Literal> newVar2oldLit = new HashMap<>();
final LiteralSubstitution substitution = new LiteralSubstitution();
for (final Literal literal : nnf.literals()) {
final Variable newVar = formula.factory().variable(literal.name() + (literal.phase() ? POS : NEG));
newVar2oldLit.put(newVar, literal);
substitution.addSubstitution(literal, newVar);
}
final Formula substitued = nnf.transform(substitution);
final SATSolver solver = MiniSat.miniSat(formula.factory(), MiniSatConfig.builder().cnfMethod(MiniSatConfig.CNFMethod.PG_ON_SOLVER).build());
solver.add(substitued);
for (final Literal literal : newVar2oldLit.values()) {
if (literal.phase() && newVar2oldLit.containsValue(literal.negate())) {
solver.add(formula.factory().amo(formula.factory().variable(literal.name() + POS), formula.factory().variable(literal.name() + NEG)));
}
}
if (solver.sat() != Tristate.TRUE) {
return null;
}
final Assignment minimumModel = solver.execute(OptimizationFunction.minimize(newVar2oldLit.keySet()));
final SortedSet<Literal> primeImplicant = new TreeSet<>();
for (final Variable variable : minimumModel.positiveVariables()) {
final Literal literal = newVar2oldLit.get(variable);
if (literal != null) {
primeImplicant.add(literal);
}
}
return primeImplicant;
}
use of org.logicng.solvers.SATSolver in project LogicNG by logic-ng.
the class SmusComputation method computeSmus.
/**
* Computes the SMUS for the given list of propositions modulo some additional constraint.
* <p>
* The SMUS computation can be called with an {@link OptimizationHandler}. The given handler instance will be used for every subsequent
* * {@link org.logicng.solvers.functions.OptimizationFunction} call and the handler's SAT handler is used for every subsequent SAT call.
* @param <P> the subtype of the propositions
* @param propositions the propositions
* @param additionalConstraints the additional constraints
* @param f the formula factory
* @param handler the handler, can be {@code null}
* @return the SMUS or {@code null} if the given propositions are satisfiable or the handler aborted the computation
*/
public static <P extends Proposition> List<P> computeSmus(final List<P> propositions, final List<Formula> additionalConstraints, final FormulaFactory f, final OptimizationHandler handler) {
start(handler);
final SATSolver growSolver = MiniSat.miniSat(f);
growSolver.add(additionalConstraints == null ? Collections.singletonList(f.verum()) : additionalConstraints);
final Map<Variable, P> propositionMapping = new TreeMap<>();
for (final P proposition : propositions) {
final Variable selector = f.variable(PROPOSITION_SELECTOR + propositionMapping.size());
propositionMapping.put(selector, proposition);
growSolver.add(f.equivalence(selector, proposition.formula()));
}
final boolean sat = growSolver.sat(satHandler(handler), propositionMapping.keySet()) == Tristate.TRUE;
if (sat || aborted(handler)) {
return null;
}
final SATSolver hSolver = MiniSat.miniSat(f);
while (true) {
final SortedSet<Variable> h = minimumHs(hSolver, propositionMapping.keySet(), handler);
if (h == null || aborted(handler)) {
return null;
}
final SortedSet<Variable> c = grow(growSolver, h, propositionMapping.keySet(), handler);
if (aborted(handler)) {
return null;
}
if (c == null) {
return h.stream().map(propositionMapping::get).collect(Collectors.toList());
}
hSolver.add(f.or(c));
}
}
use of org.logicng.solvers.SATSolver in project LogicNG by logic-ng.
the class QuineMcCluskeyAlgorithm method chooseSatBased.
/**
* Choose a minimal set of prime implicants from the final prime implicant table of QMC. This implementation uses
* a MaxSAT formulation for this variant of the SET COVER problem which should be more efficient than e.g. Petrick's
* method for all cases in which this Quine-McCluskey implementation yields a result in reasonable time.
* @param table the final prime term table
* @param f the formula factory
* @return the list of chosen prime implicants which are minimal wrt. to their number
*/
static List<Term> chooseSatBased(final TermTable table, final FormulaFactory f) {
final LinkedHashMap<Variable, Term> var2Term = new LinkedHashMap<>();
final LinkedHashMap<Formula, Variable> formula2VarMapping = new LinkedHashMap<>();
final SATSolver satSolver = initializeSolver(table, f, var2Term, formula2VarMapping);
if (satSolver.sat() == Tristate.FALSE) {
throw new IllegalStateException("Solver must be satisfiable after adding the initial formula.");
}
return minimize(satSolver, var2Term, f);
}
use of org.logicng.solvers.SATSolver in project LogicNG by logic-ng.
the class BackboneSimplifier method apply.
@Override
public Formula apply(final Formula formula, final boolean cache) {
final SATSolver solver = MiniSat.miniSat(formula.factory());
solver.add(formula);
final Backbone backbone = solver.execute(BackboneFunction.builder().variables(formula.variables()).type(BackboneType.POSITIVE_AND_NEGATIVE).build());
if (!backbone.isSat()) {
return formula.factory().falsum();
}
if (!backbone.getNegativeBackbone().isEmpty() || !backbone.getPositiveBackbone().isEmpty()) {
final Formula backboneFormula = backbone.toFormula(formula.factory());
final Assignment assignment = new Assignment(backbone.getCompleteBackbone());
final Formula restrictedFormula = formula.restrict(assignment);
return formula.factory().and(backboneFormula, restrictedFormula);
} else {
return formula;
}
}
use of org.logicng.solvers.SATSolver in project LogicNG by logic-ng.
the class CCEXKTest method testCC.
private void testCC(final int numLits, final int rhs, final int expected, final FormulaFactory f) {
final Variable[] problemLits = new Variable[numLits];
for (int i = 0; i < numLits; i++) {
problemLits[i] = f.variable("v" + i);
}
final SATSolver solver = MiniSat.miniSat(f);
solver.add(f.cc(CType.EQ, rhs, problemLits));
if (expected != 0) {
assertSolverSat(solver);
} else {
assertSolverUnsat(solver);
}
assertThat(solver.enumerateAllModels(problemLits)).hasSize(expected).allMatch(m -> m.positiveVariables().size() == rhs);
}
Aggregations