use of com.dat3m.dartagnan.utils.logic.DNF in project Dat3M by hernanponcedeleon.
the class Reasoner method computeViolationReasons.
// ========================== Reason computation ==========================
public DNF<CAATLiteral> computeViolationReasons(Constraint constraint) {
if (!constraint.checkForViolations()) {
return DNF.FALSE();
}
CAATPredicate pred = constraint.getConstrainedPredicate();
Collection<? extends Collection<? extends Derivable>> violations = constraint.getViolations();
List<Conjunction<CAATLiteral>> reasonList = new ArrayList<>(violations.size());
if (constraint instanceof AcyclicityConstraint) {
// For acyclicity constraints, it is likely that we encounter the same
// edge multiple times (as it can be part of different cycles)
// so we memoize the computed reasons and reuse them if possible.
final RelationGraph constrainedGraph = (RelationGraph) pred;
final int mapSize = violations.stream().mapToInt(Collection::size).sum() * 4 / 3;
final Map<Edge, Conjunction<CAATLiteral>> reasonMap = new HashMap<>(mapSize);
for (Collection<Edge> violation : (Collection<Collection<Edge>>) violations) {
Conjunction<CAATLiteral> reason = violation.stream().map(edge -> reasonMap.computeIfAbsent(edge, key -> computeReason(constrainedGraph, key))).reduce(Conjunction.TRUE(), Conjunction::and);
reasonList.add(reason);
}
} else {
for (Collection<? extends Derivable> violation : violations) {
Conjunction<CAATLiteral> reason = violation.stream().map(edge -> computeReason(pred, edge)).reduce(Conjunction.TRUE(), Conjunction::and);
reasonList.add(reason);
}
}
return new DNF<>(reasonList);
}
use of com.dat3m.dartagnan.utils.logic.DNF in project Dat3M by hernanponcedeleon.
the class RefinementSolver method run.
// TODO: We do not yet use Witness information. The problem is that WitnessGraph.encode() generates
// constraints on hb, which is not encoded in Refinement.
public static Result run(SolverContext ctx, ProverEnvironment prover, RefinementTask task) throws InterruptedException, SolverException, InvalidConfigurationException {
task.preprocessProgram();
if (task.getProgram().getAss() instanceof AssertTrue) {
logger.info("Verification finished: assertion trivially holds");
return PASS;
}
task.performStaticProgramAnalyses();
task.performStaticWmmAnalyses();
task.initializeEncoders(ctx);
ProgramEncoder programEncoder = task.getProgramEncoder();
PropertyEncoder propertyEncoder = task.getPropertyEncoder();
WmmEncoder baselineEncoder = task.getBaselineWmmEncoder();
SymmetryEncoder symmEncoder = task.getSymmetryEncoder();
Program program = task.getProgram();
WMMSolver solver = new WMMSolver(task);
Refiner refiner = new Refiner(task);
CAATSolver.Status status = INCONSISTENT;
logger.info("Starting encoding using " + ctx.getVersion());
prover.addConstraint(programEncoder.encodeFullProgram(ctx));
prover.addConstraint(baselineEncoder.encodeFullMemoryModel(ctx));
prover.addConstraint(symmEncoder.encodeFullSymmetry(ctx));
prover.push();
prover.addConstraint(propertyEncoder.encodeSpecification(task.getProperty(), ctx));
// ------ Just for statistics ------
List<DNF<CoreLiteral>> foundCoreReasons = new ArrayList<>();
List<WMMSolver.Statistics> statList = new ArrayList<>();
int iterationCount = 0;
long lastTime = System.currentTimeMillis();
long curTime;
long totalNativeSolvingTime = 0;
long totalCaatTime = 0;
// ---------------------------------
logger.info("Refinement procedure started.");
while (!prover.isUnsat()) {
if (iterationCount == 0 && logger.isDebugEnabled()) {
String smtStatistics = "\n ===== SMT Statistics (after first iteration) ===== \n";
for (String key : prover.getStatistics().keySet()) {
smtStatistics += String.format("\t%s -> %s\n", key, prover.getStatistics().get(key));
}
logger.debug(smtStatistics);
}
iterationCount++;
curTime = System.currentTimeMillis();
totalNativeSolvingTime += (curTime - lastTime);
logger.debug("Solver iteration: \n" + " ===== Iteration: {} =====\n" + "Solving time(ms): {}", iterationCount, curTime - lastTime);
curTime = System.currentTimeMillis();
WMMSolver.Result solverResult;
try (Model model = prover.getModel()) {
solverResult = solver.check(model, ctx);
} catch (SolverException e) {
logger.error(e);
throw e;
}
WMMSolver.Statistics stats = solverResult.getStatistics();
statList.add(stats);
logger.debug("Refinement iteration:\n{}", stats);
status = solverResult.getStatus();
if (status == INCONSISTENT) {
DNF<CoreLiteral> reasons = solverResult.getCoreReasons();
foundCoreReasons.add(reasons);
prover.addConstraint(refiner.refine(reasons, ctx));
if (REFINEMENT_GENERATE_GRAPHVIZ_DEBUG_FILES) {
generateGraphvizFiles(task, solver.getExecution(), iterationCount, reasons);
}
if (logger.isTraceEnabled()) {
// Some statistics
StringBuilder message = new StringBuilder().append("Found inconsistency reasons:");
for (Conjunction<CoreLiteral> cube : reasons.getCubes()) {
message.append("\n").append(cube);
}
logger.trace(message);
}
} else {
// No violations found, we can't refine
break;
}
totalCaatTime += (System.currentTimeMillis() - curTime);
lastTime = System.currentTimeMillis();
}
iterationCount++;
curTime = System.currentTimeMillis();
totalNativeSolvingTime += (curTime - lastTime);
logger.debug("Final solver iteration:\n" + " ===== Final Iteration: {} =====\n" + "Native Solving/Proof time(ms): {}", iterationCount, curTime - lastTime);
if (logger.isInfoEnabled()) {
String message;
switch(status) {
case INCONCLUSIVE:
message = "CAAT Solver was inconclusive (bug?).";
break;
case CONSISTENT:
message = "Violation verified.";
break;
case INCONSISTENT:
message = "Bounded safety proven.";
break;
default:
throw new IllegalStateException("Unknown result type returned by CAAT Solver.");
}
logger.info(message);
}
if (status == INCONCLUSIVE) {
// CAATSolver got no result (should not be able to happen), so we cannot proceed further.
return UNKNOWN;
}
Result veriResult;
long boundCheckTime = 0;
if (prover.isUnsat()) {
// ------- CHECK BOUNDS -------
lastTime = System.currentTimeMillis();
prover.pop();
// Add bound check
prover.addConstraint(propertyEncoder.encodeBoundEventExec(ctx));
// Add back the constraints found during Refinement (TODO: We might need to perform a second refinement)
for (DNF<CoreLiteral> reason : foundCoreReasons) {
prover.addConstraint(refiner.refine(reason, ctx));
}
veriResult = !prover.isUnsat() ? UNKNOWN : PASS;
boundCheckTime = System.currentTimeMillis() - lastTime;
} else {
veriResult = FAIL;
}
if (logger.isInfoEnabled()) {
logger.info(generateSummary(statList, iterationCount, totalNativeSolvingTime, totalCaatTime, boundCheckTime));
}
if (logger.isDebugEnabled()) {
String smtStatistics = "\n ===== SMT Statistics (after final iteration) ===== \n";
for (String key : prover.getStatistics().keySet()) {
smtStatistics += String.format("\t%s -> %s\n", key, prover.getStatistics().get(key));
}
logger.debug(smtStatistics);
}
veriResult = program.getAss().getInvert() ? veriResult.invert() : veriResult;
logger.info("Verification finished with result " + veriResult);
return veriResult;
}
use of com.dat3m.dartagnan.utils.logic.DNF in project Dat3M by hernanponcedeleon.
the class CAATSolver method computeInconsistencyReasons.
// ======================================== Reason computation ==============================================
private DNF<CAATLiteral> computeInconsistencyReasons(List<Constraint> violatedConstraints) {
List<Conjunction<CAATLiteral>> reasons = new ArrayList<>();
for (Constraint constraint : violatedConstraints) {
reasons.addAll(reasoner.computeViolationReasons(constraint).getCubes());
}
stats.numComputedReasons += reasons.size();
// The conversion to DNF removes duplicates and dominated clauses
DNF<CAATLiteral> result = new DNF<>(reasons);
stats.numComputedReducedReasons += result.getNumberOfCubes();
return result;
}
use of com.dat3m.dartagnan.utils.logic.DNF in project Dat3M by hernanponcedeleon.
the class Refiner method refine.
// This method computes a refinement clause from a set of violations.
// Furthermore, it computes symmetric violations if symmetry learning is enabled.
public BooleanFormula refine(DNF<CoreLiteral> coreReasons, SolverContext context) {
// TODO: A specialized algorithm that computes the orbit under permutation may be better,
// since most violations involve only few threads and hence the orbit is far smaller than the full
// set of permutations.
BooleanFormulaManager bmgr = context.getFormulaManager().getBooleanFormulaManager();
BooleanFormula refinement = bmgr.makeTrue();
// For each symmetry permutation, we will create refinement clauses
for (Function<Event, Event> perm : symmPermutations) {
for (Conjunction<CoreLiteral> reason : coreReasons.getCubes()) {
BooleanFormula permutedClause = reason.getLiterals().stream().map(lit -> bmgr.not(permuteAndConvert(lit, perm, context))).reduce(bmgr.makeFalse(), bmgr::or);
refinement = bmgr.and(refinement, permutedClause);
}
}
return refinement;
}
Aggregations