use of org.logicng.explanations.UNSATCore in project LogicNG by logic-ng.
the class UnsatCoreFunction method apply.
@Override
public UNSATCore<Proposition> apply(final MiniSat solver, final Consumer<Tristate> resultSetter) {
if (!solver.getConfig().proofGeneration()) {
throw new IllegalStateException("Cannot generate an unsat core if proof generation is not turned on");
}
if (solver.getResult() == TRUE) {
throw new IllegalStateException("An unsat core can only be generated if the formula is solved and is UNSAT");
}
if (solver.getResult() == Tristate.UNDEF) {
throw new IllegalStateException("Cannot generate an unsat core before the formula was solved.");
}
if (solver.underlyingSolver() instanceof MiniCard) {
throw new IllegalStateException("Cannot compute an unsat core with MiniCard.");
}
if (solver.underlyingSolver() instanceof GlucoseSyrup && solver.getConfig().incremental()) {
throw new IllegalStateException("Cannot compute an unsat core with Glucose in incremental mode.");
}
if (solver.isLastComputationWithAssumptions()) {
throw new IllegalStateException("Cannot compute an unsat core for a computation with assumptions.");
}
final DRUPTrim trimmer = new DRUPTrim();
final Map<Formula, Proposition> clause2proposition = new HashMap<>();
final LNGVector<LNGIntVector> clauses = new LNGVector<>(solver.underlyingSolver().pgOriginalClauses().size());
for (final MiniSatStyleSolver.ProofInformation pi : solver.underlyingSolver().pgOriginalClauses()) {
clauses.push(pi.clause());
final Formula clause = getFormulaForVector(solver, pi.clause());
Proposition proposition = pi.proposition();
if (proposition == null) {
proposition = new StandardProposition(clause);
}
clause2proposition.put(clause, proposition);
}
if (containsEmptyClause(clauses)) {
final Proposition emptyClause = clause2proposition.get(solver.factory().falsum());
return new UNSATCore<>(Collections.singletonList(emptyClause), true);
}
final DRUPTrim.DRUPResult result = trimmer.compute(clauses, solver.underlyingSolver().pgProof());
if (result.trivialUnsat()) {
return handleTrivialCase(solver);
}
final LinkedHashSet<Proposition> propositions = new LinkedHashSet<>();
for (final LNGIntVector vector : result.unsatCore()) {
propositions.add(clause2proposition.get(getFormulaForVector(solver, vector)));
}
return new UNSATCore<>(new ArrayList<>(propositions), false);
}
use of org.logicng.explanations.UNSATCore in project LogicNG by logic-ng.
the class DeletionBasedMUS method computeMUS.
@Override
public <T extends Proposition> UNSATCore<T> computeMUS(final List<T> propositions, final FormulaFactory f, final MUSConfig config) {
start(config.handler);
final List<T> mus = new ArrayList<>(propositions.size());
final List<SolverState> solverStates = new ArrayList<>(propositions.size());
final MiniSat solver = MiniSat.miniSat(f);
for (final Proposition proposition : propositions) {
solverStates.add(solver.saveState());
solver.add(proposition);
}
boolean sat = solver.sat() == Tristate.TRUE;
if (aborted(config.handler)) {
return null;
}
if (sat) {
throw new IllegalArgumentException("Cannot compute a MUS for a satisfiable formula set.");
}
for (int i = solverStates.size() - 1; i >= 0; i--) {
solver.loadState(solverStates.get(i));
for (final Proposition prop : mus) {
solver.add(prop);
}
sat = solver.sat(config.handler) == Tristate.TRUE;
if (aborted(config.handler)) {
return null;
}
if (sat) {
mus.add(propositions.get(i));
}
}
return new UNSATCore<>(mus, true);
}
use of org.logicng.explanations.UNSATCore in project LogicNG by logic-ng.
the class PlainInsertionBasedMUS method computeMUS.
@Override
public <T extends Proposition> UNSATCore<T> computeMUS(final List<T> propositions, final FormulaFactory f, final MUSConfig config) {
start(config.handler);
final List<T> currentFormula = new ArrayList<>(propositions.size());
currentFormula.addAll(propositions);
final List<T> mus = new ArrayList<>(propositions.size());
final MiniSat solver = MiniSat.miniSat(f);
while (!currentFormula.isEmpty()) {
final List<T> currentSubset = new ArrayList<>(propositions.size());
T transitionProposition = null;
solver.reset();
for (final Proposition p : mus) {
solver.add(p);
}
int count = currentFormula.size();
while (shouldProceed(solver, config.handler)) {
if (count == 0) {
throw new IllegalArgumentException("Cannot compute a MUS for a satisfiable formula set.");
}
final T removeProposition = currentFormula.get(--count);
currentSubset.add(removeProposition);
transitionProposition = removeProposition;
solver.add(removeProposition);
}
if (aborted(config.handler)) {
return null;
}
currentFormula.clear();
currentFormula.addAll(currentSubset);
if (transitionProposition != null) {
currentFormula.remove(transitionProposition);
mus.add(transitionProposition);
}
}
return new UNSATCore<>(mus, true);
}
use of org.logicng.explanations.UNSATCore in project LogicNG by logic-ng.
the class UnsatCoreFunction method handleTrivialCase.
private UNSATCore<Proposition> handleTrivialCase(final MiniSat solver) {
final LNGVector<MiniSatStyleSolver.ProofInformation> clauses = solver.underlyingSolver().pgOriginalClauses();
for (int i = 0; i < clauses.size(); i++) {
for (int j = i + 1; j < clauses.size(); j++) {
if (clauses.get(i).clause().size() == 1 && clauses.get(j).clause().size() == 1 && clauses.get(i).clause().get(0) + clauses.get(j).clause().get(0) == 0) {
final LinkedHashSet<Proposition> propositions = new LinkedHashSet<>();
final Proposition pi = clauses.get(i).proposition();
final Proposition pj = clauses.get(j).proposition();
propositions.add(pi != null ? pi : new StandardProposition(getFormulaForVector(solver, clauses.get(i).clause())));
propositions.add(pj != null ? pj : new StandardProposition(getFormulaForVector(solver, clauses.get(j).clause())));
return new UNSATCore<>(new ArrayList<>(propositions), false);
}
}
}
throw new IllegalStateException("Should be a trivial unsat core, but did not found one.");
}
Aggregations