use of com.dat3m.dartagnan.configuration.Property in project Dat3M by hernanponcedeleon.
the class Dartagnan method main.
public static void main(String[] args) throws Exception {
if (Arrays.asList(args).contains("--help")) {
collectOptions();
return;
}
CreateGitInfo();
String[] argKeyword = Arrays.stream(args).filter(s -> s.startsWith("-")).toArray(String[]::new);
// TODO: We don't parse configs yet
Configuration config = Configuration.fromCmdLineArguments(argKeyword);
Dartagnan o = new Dartagnan(config);
if (Arrays.stream(args).noneMatch(a -> supportedFormats.stream().anyMatch(a::endsWith))) {
throw new IllegalArgumentException("Input program not given or format not recognized");
}
// get() is guaranteed to success
File fileProgram = new File(Arrays.stream(args).filter(a -> supportedFormats.stream().anyMatch(a::endsWith)).findFirst().get());
logger.info("Program path: " + fileProgram);
if (Arrays.stream(args).noneMatch(a -> a.endsWith(".cat"))) {
throw new IllegalArgumentException("CAT model not given or format not recognized");
}
// get() is guaranteed to success
File fileModel = new File(Arrays.stream(args).filter(a -> a.endsWith(".cat")).findFirst().get());
logger.info("CAT file path: " + fileModel);
Wmm mcm = new ParserCat().parse(fileModel);
Program p = new ProgramParser().parse(fileProgram);
EnumSet<Property> properties = o.getProperty();
WitnessGraph witness = new WitnessGraph();
if (o.runValidator()) {
logger.info("Witness path: " + o.getWitnessPath());
witness = new ParserWitness().parse(new File(o.getWitnessPath()));
}
VerificationTask task = VerificationTask.builder().withConfig(config).withWitness(witness).build(p, mcm, properties);
ShutdownManager sdm = ShutdownManager.create();
Thread t = new Thread(() -> {
try {
if (o.hasTimeout()) {
// Converts timeout from secs to millisecs
Thread.sleep(1000L * o.getTimeout());
sdm.requestShutdown("Shutdown Request");
logger.warn("Shutdown Request");
}
} catch (InterruptedException e) {
// Verification ended, nothing to be done.
}
});
try {
t.start();
Configuration solverConfig = Configuration.builder().setOption(PHANTOM_REFERENCES, valueOf(o.usePhantomReferences())).build();
try (SolverContext ctx = SolverContextFactory.createSolverContext(solverConfig, BasicLogManager.create(solverConfig), sdm.getNotifier(), o.getSolver());
ProverEnvironment prover = ctx.newProverEnvironment(ProverOptions.GENERATE_MODELS)) {
Result result = UNKNOWN;
if (properties.contains(RACES)) {
if (properties.size() > 1) {
System.out.println("Data race detection cannot be combined with other properties");
System.exit(1);
}
result = DataRaceSolver.run(ctx, prover, task);
} else {
// Property is either LIVENESS and/or REACHABILITY
switch(o.getMethod()) {
case TWO:
try (ProverEnvironment prover2 = ctx.newProverEnvironment(ProverOptions.GENERATE_MODELS)) {
result = TwoSolvers.run(ctx, prover, prover2, task);
}
break;
case INCREMENTAL:
result = IncrementalSolver.run(ctx, prover, task);
break;
case ASSUME:
result = AssumeSolver.run(ctx, prover, task);
break;
case CAAT:
result = RefinementSolver.run(ctx, prover, RefinementTask.fromVerificationTaskWithDefaultBaselineWMM(task));
break;
}
}
// Verification ended, we can interrupt the timeout Thread
t.interrupt();
if (result.equals(FAIL) && o.generateGraphviz()) {
ExecutionModel m = new ExecutionModel(task);
m.initialize(prover.getModel(), ctx);
String name = task.getProgram().getName().substring(0, task.getProgram().getName().lastIndexOf('.'));
generateGraphvizFile(m, 1, (x, y) -> true, System.getenv("DAT3M_HOME") + "/output/", name);
}
if (p.getFormat().equals(SourceLanguage.LITMUS)) {
if (p.getAssFilter() != null) {
System.out.println("Filter " + (p.getAssFilter()));
}
System.out.println("Condition " + p.getAss().toStringWithType());
System.out.println(result == FAIL ? "Ok" : "No");
} else {
if (result == FAIL) {
if (TRUE.equals(prover.getModel().evaluate(REACHABILITY.getSMTVariable(ctx)))) {
System.out.println("Safety violation found");
}
if (TRUE.equals(prover.getModel().evaluate(LIVENESS.getSMTVariable(ctx)))) {
System.out.println("Liveness violation found");
}
}
System.out.println(result);
}
try {
WitnessBuilder w = new WitnessBuilder(task, ctx, prover, result);
// and if we are not doing witness validation
if (properties.contains(REACHABILITY) && w.canBeBuilt() && !o.runValidator()) {
w.build().write();
}
} catch (InvalidConfigurationException e) {
logger.warn(e.getMessage());
}
}
} catch (InterruptedException e) {
logger.warn("Timeout elapsed. The SMT solver was stopped");
System.out.println("TIMEOUT");
System.exit(0);
} catch (Exception e) {
logger.error(e.getMessage());
System.out.println("ERROR");
System.exit(1);
}
}
use of com.dat3m.dartagnan.configuration.Property in project Dat3M by hernanponcedeleon.
the class PropertyEncoder method encodeDataRaces.
public BooleanFormula encodeDataRaces(SolverContext ctx) {
final String hb = "hb";
checkState(memoryModel.getAxioms().stream().anyMatch(ax -> ax.isAcyclicity() && ax.getRelation().getName().equals(hb)), "The provided WMM needs an 'acyclic(hb)' axiom to encode data races.");
logger.info("Encoding data-races");
BooleanFormulaManager bmgr = ctx.getFormulaManager().getBooleanFormulaManager();
IntegerFormulaManager imgr = ctx.getFormulaManager().getIntegerFormulaManager();
BooleanFormula enc = bmgr.makeFalse();
for (Thread t1 : program.getThreads()) {
for (Thread t2 : program.getThreads()) {
if (t1.getId() == t2.getId()) {
continue;
}
for (Event e1 : t1.getCache().getEvents(FilterMinus.get(FilterBasic.get(Tag.WRITE), FilterBasic.get(Tag.INIT)))) {
MemEvent w = (MemEvent) e1;
for (Event e2 : t2.getCache().getEvents(FilterMinus.get(FilterBasic.get(Tag.MEMORY), FilterBasic.get(Tag.INIT)))) {
MemEvent m = (MemEvent) e2;
if (w.hasFilter(Tag.RMW) && m.hasFilter(Tag.RMW)) {
continue;
}
if (w.canRace() && m.canRace() && alias.mayAlias(w, m)) {
BooleanFormula conflict = bmgr.and(m.exec(), w.exec(), edge(hb, m, w, ctx), generalEqual(w.getMemAddressExpr(), m.getMemAddressExpr(), ctx), imgr.equal(intVar(hb, w, ctx), imgr.add(intVar(hb, m, ctx), imgr.makeNumber(BigInteger.ONE))));
enc = bmgr.or(enc, conflict);
}
}
}
}
}
// We use the SMT variable to extract from the model if the property was violated
enc = bmgr.equivalence(RACES.getSMTVariable(ctx), enc);
return bmgr.and(RACES.getSMTVariable(ctx), enc);
}
use of com.dat3m.dartagnan.configuration.Property in project Dat3M by hernanponcedeleon.
the class PropertyEncoder method encodeLiveness.
public BooleanFormula encodeLiveness(SolverContext ctx) {
// Further, we assume that the spinloops are indeed correct, i.e., side-effect free
class SpinLoop {
public List<Load> loads = new ArrayList<>();
public Event bound;
}
logger.info("Encoding liveness");
Map<Thread, List<SpinLoop>> spinloopsMap = new HashMap<>();
// Find spinloops of all threads
for (Thread t : program.getThreads()) {
List<Event> spinStarts = t.getEvents().stream().filter(e -> e instanceof Label && e.is(Tag.SPINLOOP)).collect(Collectors.toList());
List<SpinLoop> spinLoops = new ArrayList<>();
spinloopsMap.put(t, spinLoops);
for (Event start : spinStarts) {
SpinLoop loop = new SpinLoop();
Event cur = start.getSuccessor();
while (!cur.is(Tag.SPINLOOP)) {
if (cur.is(Tag.READ)) {
loop.loads.add((Load) cur);
}
cur = cur.getSuccessor();
}
loop.bound = cur;
spinLoops.add(loop);
}
}
BooleanFormulaManager bmgr = ctx.getFormulaManager().getBooleanFormulaManager();
RelRf rf = (RelRf) memoryModel.getRelationRepository().getRelation(RelationNameRepository.RF);
RelCo co = (RelCo) memoryModel.getRelationRepository().getRelation(RelationNameRepository.CO);
// Compute "stuckness": A thread is stuck if it reaches a spinloop bound event
// while reading from a co-maximal write.
Map<Thread, BooleanFormula> isStuckMap = new HashMap<>();
for (Thread t : program.getThreads()) {
List<SpinLoop> loops = spinloopsMap.get(t);
if (loops.isEmpty()) {
continue;
}
BooleanFormula isStuck = bmgr.makeFalse();
for (SpinLoop pair : loops) {
BooleanFormula allCoMaximalLoad = bmgr.makeTrue();
for (Load load : pair.loads) {
BooleanFormula coMaximalLoad = bmgr.makeFalse();
for (Tuple rfEdge : rf.getMaxTupleSet().getBySecond(load)) {
coMaximalLoad = bmgr.or(coMaximalLoad, bmgr.and(rf.getSMTVar(rfEdge, ctx), co.getLastCoVar(rfEdge.getFirst(), ctx)));
}
allCoMaximalLoad = bmgr.and(allCoMaximalLoad, coMaximalLoad);
}
isStuck = bmgr.or(isStuck, bmgr.and(pair.bound.exec(), allCoMaximalLoad));
}
isStuckMap.put(t, isStuck);
}
// LivenessViolation <=> allStuckOrDone /\ atLeastOneStuck
BooleanFormula allStuckOrDone = bmgr.makeTrue();
BooleanFormula atLeastOneStuck = bmgr.makeFalse();
for (Thread t : program.getThreads()) {
BooleanFormula isStuck = isStuckMap.getOrDefault(t, bmgr.makeFalse());
BooleanFormula isDone = t.getCache().getEvents(FilterBasic.get(Tag.BOUND)).stream().map(e -> bmgr.not(e.exec())).reduce(bmgr.makeTrue(), bmgr::and);
atLeastOneStuck = bmgr.or(atLeastOneStuck, isStuck);
allStuckOrDone = bmgr.and(allStuckOrDone, bmgr.or(isStuck, isDone));
}
// We use the SMT variable to extract from the model if the property was violated
BooleanFormula enc = bmgr.equivalence(LIVENESS.getSMTVariable(ctx), bmgr.and(allStuckOrDone, atLeastOneStuck));
return bmgr.and(LIVENESS.getSMTVariable(ctx), enc);
}
use of com.dat3m.dartagnan.configuration.Property in project Dat3M by hernanponcedeleon.
the class SVCOMPRunner method main.
public static void main(String[] args) throws Exception {
if (Arrays.asList(args).contains("--help")) {
collectOptions();
return;
}
if (Arrays.stream(args).noneMatch(a -> supportedFormats.stream().anyMatch(a::endsWith))) {
throw new IllegalArgumentException("Input program not given or format not recognized");
}
if (Arrays.stream(args).noneMatch(a -> a.endsWith(".cat"))) {
throw new IllegalArgumentException("CAT model not given or format not recognized");
}
File fileModel = new File(Arrays.stream(args).filter(a -> a.endsWith(".cat")).findFirst().get());
String programPath = Arrays.stream(args).filter(a -> supportedFormats.stream().anyMatch(a::endsWith)).findFirst().get();
File fileProgram = new File(programPath);
String[] argKeyword = Arrays.stream(args).filter(s -> s.startsWith("-")).toArray(String[]::new);
Configuration config = Configuration.fromCmdLineArguments(argKeyword);
SVCOMPRunner r = new SVCOMPRunner();
config.recursiveInject(r);
WitnessGraph witness = new WitnessGraph();
if (r.witnessPath != null) {
witness = new ParserWitness().parse(new File(r.witnessPath));
if (!fileProgram.getName().equals(Paths.get(witness.getProgram()).getFileName().toString())) {
throw new RuntimeException("The witness was generated from a different program than " + fileProgram);
}
}
int bound = witness.hasAttributed(UNROLLBOUND.toString()) ? parseInt(witness.getAttributed(UNROLLBOUND.toString())) : r.umin;
File tmp = new SVCOMPSanitizer(fileProgram).run(bound);
// First time we compiler with standard atomic header to catch compilation problems
compileWithClang(tmp);
String output = "UNKNOWN";
while (output.equals("UNKNOWN")) {
compileWithSmack(tmp);
// If not removed here, file is not removed when we reach the timeout
// File can be safely deleted since it was created by the SVCOMPSanitizer
// (it not the original C file) and we already created the Boogie file
tmp.delete();
String boogieName = System.getenv().get("DAT3M_HOME") + "/output/" + Files.getNameWithoutExtension(programPath) + ".bpl";
if (r.sanitize) {
BoogieSan.write(boogieName);
}
ArrayList<String> cmd = new ArrayList<>();
cmd.add("java");
cmd.add("-Dlog4j.configurationFile=" + System.getenv().get("DAT3M_HOME") + "/dartagnan/src/main/resources/log4j2.xml");
cmd.add("-DLOGNAME=" + Files.getNameWithoutExtension(programPath));
cmd.addAll(Arrays.asList("-jar", System.getenv().get("DAT3M_HOME") + "/dartagnan/target/dartagnan-3.0.0.jar"));
cmd.add(fileModel.toString());
cmd.add(boogieName);
cmd.add(String.format("--%s=%s", PROPERTY, r.property.asStringOption()));
cmd.add(String.format("--%s=%s", BOUND, bound));
cmd.add(String.format("--%s=%s", WITNESS_ORIGINAL_PROGRAM_PATH, programPath));
cmd.addAll(filterOptions(config));
ProcessBuilder processBuilder = new ProcessBuilder(cmd);
try {
Process proc = processBuilder.start();
BufferedReader read = new BufferedReader(new InputStreamReader(proc.getInputStream()));
proc.waitFor();
while (read.ready()) {
output = read.readLine();
System.out.println(output);
}
if (proc.exitValue() == 1) {
BufferedReader error = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
while (error.ready()) {
System.out.println(error.readLine());
}
System.exit(0);
}
} catch (Exception e) {
System.out.println(e.getMessage());
System.exit(0);
}
if (bound > r.umax) {
System.out.println("PASS");
break;
}
// We always do iterations 1 and 2 and then use the step
bound = bound == 1 ? 2 : bound + r.step;
tmp = new SVCOMPSanitizer(fileProgram).run(bound);
}
tmp.delete();
}
Aggregations