use of com.dat3m.dartagnan.program.Thread in project Dat3M by hernanponcedeleon.
the class CoSymmetryBreaking method encode.
public BooleanFormula encode(EquivalenceClass<Thread> symmClass, SolverContext ctx) {
BooleanFormulaManager bmgr = ctx.getFormulaManager().getBooleanFormulaManager();
BooleanFormula enc = bmgr.makeTrue();
if (symmClass.getEquivalence() != symm) {
return enc;
}
Info info = infoMap.get(symmClass);
if (info == null) {
logger.warn("Cannot encode co-symmetry because no information has been computed. " + "Make sure that <initialize> gets called before encoding.");
return enc;
}
List<Thread> symmThreads = info.threads;
// ============= Construct rows =============
Thread t1 = symmThreads.get(0);
List<Thread> otherThreads = symmThreads.subList(1, symmThreads.size());
List<Tuple> r1Tuples = new ArrayList<>();
for (Store w : info.writes) {
for (Thread t2 : otherThreads) {
r1Tuples.add(new Tuple(w, symm.map(w, t2)));
}
}
// Starting row
List<BooleanFormula> r1 = new ArrayList<>(r1Tuples.size() + 1);
if (info.hasMustEdges) {
r1.add(info.writes.get(0).exec());
}
r1.addAll(Lists.transform(r1Tuples, t -> co.getSMTVar(t, ctx)));
// Construct symmetric rows
Thread rep = symmClass.getRepresentative();
for (int i = 1; i < symmThreads.size(); i++) {
Thread t2 = symmThreads.get(i);
Function<Event, Event> p = symm.createTransposition(t1, t2);
List<Tuple> r2Tuples = r1Tuples.stream().map(t -> t.permute(p)).collect(Collectors.toList());
List<BooleanFormula> r2 = new ArrayList<>(r2Tuples.size() + 1);
if (info.hasMustEdges) {
r2.add(symm.map(info.writes.get(0), t2).exec());
}
r2.addAll(Lists.transform(r2Tuples, t -> co.getSMTVar(t, ctx)));
final String id = "_" + rep.getId() + "_" + i;
// NOTE: We want to have r1 >= r2 but lexLeader encodes r1 <= r2, so we swap r1 and r2.
enc = bmgr.and(enc, SymmetryEncoder.encodeLexLeader(id, r2, r1, ctx));
t1 = t2;
r1Tuples = r2Tuples;
r1 = r2;
}
return enc;
}
use of com.dat3m.dartagnan.program.Thread in project Dat3M by hernanponcedeleon.
the class FenceGraph method repopulate.
@Override
public void repopulate() {
threadFencesMap = new HashMap<>();
for (Thread t : model.getThreads()) {
threadFencesMap.put(t, new ArrayList<>());
}
Set<EventData> fenceEvents = model.getFenceMap().get(fenceName);
if (fenceEvents == null) {
return;
}
for (EventData fence : fenceEvents) {
threadFencesMap.get(fence.getThread()).add(fence);
}
for (List<EventData> fenceList : threadFencesMap.values()) {
fenceList.sort(Comparator.comparingInt(EventData::getLocalId));
}
super.autoComputeSize();
}
use of com.dat3m.dartagnan.program.Thread in project Dat3M by hernanponcedeleon.
the class RelCrit method encodeApprox.
// TODO: Not the most efficient implementation
// Let's see if we need to keep a reference to a thread in events for anything else, and then optimize this method
@Override
protected BooleanFormula encodeApprox(SolverContext ctx) {
BooleanFormulaManager bmgr = ctx.getFormulaManager().getBooleanFormulaManager();
BooleanFormula enc = bmgr.makeTrue();
for (Thread thread : task.getProgram().getThreads()) {
for (Event lock : thread.getCache().getEvents(FilterBasic.get(Tag.Linux.RCU_LOCK))) {
for (Event unlock : thread.getCache().getEvents(FilterBasic.get(Tag.Linux.RCU_UNLOCK))) {
if (lock.getCId() < unlock.getCId()) {
Tuple tuple = new Tuple(lock, unlock);
if (encodeTupleSet.contains(tuple)) {
BooleanFormula relation = bmgr.and(getExecPair(lock, unlock, ctx));
for (Event otherLock : thread.getCache().getEvents(FilterBasic.get(Tag.Linux.RCU_LOCK))) {
if (lock.getCId() < otherLock.getCId() && otherLock.getCId() < unlock.getCId()) {
relation = bmgr.and(relation, bmgr.not(this.getSMTVar(otherLock, unlock, ctx)));
}
}
for (Event otherUnlock : thread.getCache().getEvents(FilterBasic.get(Tag.Linux.RCU_UNLOCK))) {
if (lock.getCId() < otherUnlock.getCId() && otherUnlock.getCId() < unlock.getCId()) {
relation = bmgr.and(relation, bmgr.not(this.getSMTVar(lock, otherUnlock, ctx)));
}
}
enc = bmgr.and(enc, bmgr.equivalence(this.getSMTVar(tuple, ctx), relation));
}
}
}
}
}
return enc;
}
use of com.dat3m.dartagnan.program.Thread in project Dat3M by hernanponcedeleon.
the class RelRMW method getMaxTupleSet.
@Override
public TupleSet getMaxTupleSet() {
if (maxTupleSet == null) {
logger.info("Computing maxTupleSet for " + getName());
baseMaxTupleSet = new TupleSet();
// RMWLoad -> RMWStore
FilterAbstract filter = FilterIntersection.get(FilterBasic.get(Tag.RMW), FilterBasic.get(Tag.WRITE));
for (Event store : task.getProgram().getCache().getEvents(filter)) {
if (store instanceof RMWStore) {
baseMaxTupleSet.add(new Tuple(((RMWStore) store).getLoadEvent(), store));
}
}
// Locks: Load -> Assume/CondJump -> Store
FilterAbstract locks = FilterUnion.get(FilterBasic.get(Tag.C11.LOCK), FilterBasic.get(Tag.Linux.LOCK_READ));
filter = FilterIntersection.get(FilterBasic.get(Tag.RMW), locks);
for (Event e : task.getProgram().getCache().getEvents(filter)) {
// Connect Load to Store
baseMaxTupleSet.add(new Tuple(e, e.getSuccessor().getSuccessor()));
}
// Atomics blocks: BeginAtomic -> EndAtomic
filter = FilterIntersection.get(FilterBasic.get(Tag.RMW), FilterBasic.get(SVCOMPATOMIC));
for (Event end : task.getProgram().getCache().getEvents(filter)) {
List<Event> block = ((EndAtomic) end).getBlock().stream().filter(x -> x.is(Tag.VISIBLE)).collect(Collectors.toList());
for (int i = 0; i < block.size(); i++) {
for (int j = i + 1; j < block.size(); j++) {
baseMaxTupleSet.add(new Tuple(block.get(i), block.get(j)));
}
}
}
removeMutuallyExclusiveTuples(baseMaxTupleSet);
maxTupleSet = new TupleSet();
maxTupleSet.addAll(baseMaxTupleSet);
// to find guaranteed pairs (the encoding can then also be improved)
for (Thread thread : task.getProgram().getThreads()) {
for (Event load : thread.getCache().getEvents(loadExclFilter)) {
for (Event store : thread.getCache().getEvents(storeExclFilter)) {
if (load.getCId() < store.getCId()) {
maxTupleSet.add(new Tuple(load, store));
}
}
}
}
removeMutuallyExclusiveTuples(maxTupleSet);
logger.info("maxTupleSet size for " + getName() + ": " + maxTupleSet.size());
}
return maxTupleSet;
}
use of com.dat3m.dartagnan.program.Thread in project Dat3M by hernanponcedeleon.
the class WitnessBuilder method build.
public WitnessGraph build() {
for (Thread t : task.getProgram().getThreads()) {
for (Event e : t.getEntry().getSuccessors()) {
eventThreadMap.put(e, t.getId() - 1);
}
}
WitnessGraph graph = new WitnessGraph();
graph.addAttribute(UNROLLBOUND.toString(), valueOf(task.getProgram().getUnrollingBound()));
graph.addAttribute(WITNESSTYPE.toString(), type + "_witness");
graph.addAttribute(SOURCECODELANG.toString(), "C");
graph.addAttribute(PRODUCER.toString(), "Dartagnan");
graph.addAttribute(SPECIFICATION.toString(), "CHECK( init(main()), LTL(G ! call(reach_error())))");
graph.addAttribute(PROGRAMFILE.toString(), originalProgramFilePath);
graph.addAttribute(PROGRAMHASH.toString(), getFileSHA256(new File(originalProgramFilePath)));
graph.addAttribute(ARCHITECTURE.toString(), "32bit");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
// "If the timestamp is in UTC time, it ends with a 'Z'."
// https://github.com/sosy-lab/sv-witnesses/blob/main/README-GraphML.md
graph.addAttribute(CREATIONTIME.toString(), df.format(new Date()) + "Z");
Node v0 = new Node("N0");
v0.addAttribute("entry", "true");
Node v1 = new Node("N1");
Node v2 = new Node("N2");
Edge edge = new Edge(v0, v1);
edge.addAttribute(CREATETHREAD.toString(), "0");
graph.addEdge(edge);
edge = new Edge(v1, v2);
edge.addAttribute(THREADID.toString(), "0");
edge.addAttribute(ENTERFUNCTION.toString(), "main");
graph.addEdge(edge);
int nextNode = 2;
int threads = 1;
if (type.equals("correctness")) {
return graph;
}
try (Model model = prover.getModel()) {
List<Event> execution = reOrderBasedOnAtomicity(task.getProgram(), getSCExecutionOrder(model));
for (int i = 0; i < execution.size(); i++) {
Event e = execution.get(i);
if (i + 1 < execution.size()) {
Event next = execution.get(i + 1);
if (e.getCLine() == next.getCLine() && e.getThread() == next.getThread()) {
continue;
}
}
edge = new Edge(new Node("N" + nextNode), new Node("N" + (nextNode + 1)));
edge.addAttribute(THREADID.toString(), valueOf(eventThreadMap.get(e)));
edge.addAttribute(STARTLINE.toString(), valueOf(e.getCLine()));
// CLines and thus won't create an edge (as expected)
if (e.hasFilter(WRITE) && e.hasFilter(PTHREAD)) {
edge.addAttribute(CREATETHREAD.toString(), valueOf(threads));
threads++;
}
if (e instanceof Load) {
RegWriter l = (RegWriter) e;
edge.addAttribute(EVENTID.toString(), valueOf(e.getUId()));
edge.addAttribute(LOADEDVALUE.toString(), l.getWrittenValue(e, model, ctx).toString());
}
if (e instanceof Store) {
Store s = (Store) e;
edge.addAttribute(EVENTID.toString(), valueOf(e.getUId()));
edge.addAttribute(STOREDVALUE.toString(), s.getMemValue().getIntValue(s, model, ctx).toString());
}
graph.addEdge(edge);
nextNode++;
if (e.hasFilter(Tag.ASSERTION)) {
break;
}
}
} catch (SolverException ignore) {
// The if above guarantees that if we reach this try, a Model exists
}
graph.getNode("N" + nextNode).addAttribute("violation", "true");
return graph;
}
Aggregations