use of com.dat3m.dartagnan.utils.equivalence.EquivalenceClass in project Dat3M by hernanponcedeleon.
the class SymmetryEncoder method encodeSymmetryClass.
public BooleanFormula encodeSymmetryClass(EquivalenceClass<Thread> symmClass, SolverContext ctx) {
BooleanFormulaManager bmgr = ctx.getFormulaManager().getBooleanFormulaManager();
BooleanFormula enc = bmgr.makeTrue();
if (rel == null || symmClass.getEquivalence() != symm) {
return enc;
}
Thread rep = symmClass.getRepresentative();
List<Thread> symmThreads = new ArrayList<>(symmClass);
symmThreads.sort(Comparator.comparingInt(Thread::getId));
// ===== Construct row =====
// IMPORTANT: Each thread writes to its own special location for the purpose of starting/terminating threads
// These need to get skipped.
Thread t1 = symmThreads.get(0);
List<Tuple> r1Tuples = new ArrayList<>();
for (Tuple t : rel.getMaxTupleSet()) {
Event a = t.getFirst();
Event b = t.getSecond();
if (!a.is(Tag.C11.PTHREAD) && !b.is(Tag.C11.PTHREAD) && a.getThread() == t1) {
r1Tuples.add(t);
}
}
sort(r1Tuples);
// Construct symmetric rows
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> r1 = Lists.transform(r1Tuples, t -> rel.getSMTVar(t, ctx));
List<BooleanFormula> r2 = Lists.transform(r2Tuples, t -> rel.getSMTVar(t, ctx));
final String id = "_" + rep.getId() + "_" + i;
// r1 >= r2
enc = bmgr.and(enc, encodeLexLeader(id, r2, r1, ctx));
t1 = t2;
r1Tuples = r2Tuples;
}
return enc;
}
use of com.dat3m.dartagnan.utils.equivalence.EquivalenceClass 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.utils.equivalence.EquivalenceClass in project Dat3M by hernanponcedeleon.
the class SymmetryReduction method run.
public void run(Program program) {
ThreadSymmetry symm = ThreadSymmetry.withoutMappings(program);
Set<? extends EquivalenceClass<Thread>> symmClasses = symm.getNonTrivialClasses();
if (symmClasses.isEmpty()) {
return;
}
for (EquivalenceClass<Thread> c : symmClasses) {
Thread rep = c.getRepresentative();
if (rep.getEvents().stream().noneMatch(x -> x.is(Tag.ASSERTION))) {
continue;
}
rep.setName(rep.getName() + "__symm_unique");
for (Thread t : c.stream().filter(x -> x != rep).collect(Collectors.toList())) {
for (Event e : t.getEvents()) {
if (e.is(Tag.ASSERTION)) {
e.getSuccessor().delete();
e.delete();
}
}
t.clearCache();
}
}
logger.info("Reduced symmetry of {} many symmetry classes", symmClasses.size());
}
Aggregations