Search in sources :

Example 26 with Tuple

use of com.dat3m.dartagnan.wmm.utils.Tuple in project Dat3M by hernanponcedeleon.

the class RelMinus method encodeApprox.

@Override
protected BooleanFormula encodeApprox(SolverContext ctx) {
    BooleanFormulaManager bmgr = ctx.getFormulaManager().getBooleanFormulaManager();
    BooleanFormula enc = bmgr.makeTrue();
    TupleSet min = getMinTupleSet();
    for (Tuple tuple : encodeTupleSet) {
        if (min.contains(tuple)) {
            enc = bmgr.and(enc, bmgr.equivalence(this.getSMTVar(tuple, ctx), getExecPair(tuple, ctx)));
            continue;
        }
        BooleanFormula opt1 = r1.getSMTVar(tuple, ctx);
        BooleanFormula opt2 = bmgr.not(r2.getSMTVar(tuple, ctx));
        if (Relation.PostFixApprox) {
            enc = bmgr.and(enc, bmgr.implication(bmgr.and(opt1, opt2), this.getSMTVar(tuple, ctx)));
        } else {
            enc = bmgr.and(enc, bmgr.equivalence(this.getSMTVar(tuple, ctx), bmgr.and(opt1, opt2)));
        }
    }
    return enc;
}
Also used : TupleSet(com.dat3m.dartagnan.wmm.utils.TupleSet) BooleanFormulaManager(org.sosy_lab.java_smt.api.BooleanFormulaManager) BooleanFormula(org.sosy_lab.java_smt.api.BooleanFormula) Tuple(com.dat3m.dartagnan.wmm.utils.Tuple)

Example 27 with Tuple

use of com.dat3m.dartagnan.wmm.utils.Tuple in project Dat3M by hernanponcedeleon.

the class BasicRegRelation method doEncodeApprox.

BooleanFormula doEncodeApprox(Collection<Event> regReaders, SolverContext ctx) {
    FormulaManager fmgr = ctx.getFormulaManager();
    BooleanFormulaManager bmgr = fmgr.getBooleanFormulaManager();
    BooleanFormula enc = bmgr.makeTrue();
    ImmutableMap<Register, ImmutableList<Event>> regWriterMap = task.getProgram().getCache().getRegWriterMap();
    for (Event regReader : regReaders) {
        Set<Tuple> writerReaders = maxTupleSet.getBySecond(regReader);
        for (Register register : getRegisters(regReader)) {
            List<Event> writers = regWriterMap.getOrDefault(register, ImmutableList.of());
            List<Event> possibleWriters = writers.stream().filter(x -> writerReaders.contains(new Tuple(x, regReader))).collect(Collectors.toList());
            if (writers.isEmpty() || writers.get(0).getCId() >= regReader.getCId()) {
                BooleanFormula equal = generalEqual(register.toIntFormula(regReader, ctx), new IValue(BigInteger.ZERO, register.getPrecision()).toIntFormula(ctx), ctx);
                enc = bmgr.and(enc, equal);
            } else {
                for (int i = 0; i < possibleWriters.size(); i++) {
                    Event regWriter = possibleWriters.get(i);
                    // RegReader uses the value of RegWriter if it is executed ..
                    BooleanFormula clause = getExecPair(regWriter, regReader, ctx);
                    BooleanFormula edge = this.getSMTVar(regWriter, regReader, ctx);
                    // .. and no other write to the same register is executed in between
                    for (int j = i + 1; j < possibleWriters.size(); j++) {
                        clause = bmgr.and(clause, bmgr.not(possibleWriters.get(j).exec()));
                    }
                    // Encode edge and value binding
                    enc = bmgr.and(enc, bmgr.equivalence(edge, clause));
                    BooleanFormula equal = generalEqual(((RegWriter) regWriter).getResultRegisterExpr(), register.toIntFormula(regReader, ctx), ctx);
                    enc = bmgr.and(enc, bmgr.implication(edge, equal));
                }
            }
        }
    }
    return enc;
}
Also used : FormulaManager(org.sosy_lab.java_smt.api.FormulaManager) ImmutableMap(com.google.common.collect.ImmutableMap) ExecutionAnalysis(com.dat3m.dartagnan.program.analysis.ExecutionAnalysis) Collection(java.util.Collection) BooleanFormula(org.sosy_lab.java_smt.api.BooleanFormula) Set(java.util.Set) Collectors(java.util.stream.Collectors) BooleanFormulaManager(org.sosy_lab.java_smt.api.BooleanFormulaManager) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) TupleSet(com.dat3m.dartagnan.wmm.utils.TupleSet) SolverContext(org.sosy_lab.java_smt.api.SolverContext) IValue(com.dat3m.dartagnan.expression.IValue) Event(com.dat3m.dartagnan.program.event.core.Event) Tuple(com.dat3m.dartagnan.wmm.utils.Tuple) BigInteger(java.math.BigInteger) Register(com.dat3m.dartagnan.program.Register) RegWriter(com.dat3m.dartagnan.program.event.core.utils.RegWriter) StaticRelation(com.dat3m.dartagnan.wmm.relation.base.stat.StaticRelation) Utils.generalEqual(com.dat3m.dartagnan.expression.utils.Utils.generalEqual) BooleanFormulaManager(org.sosy_lab.java_smt.api.BooleanFormulaManager) ImmutableList(com.google.common.collect.ImmutableList) IValue(com.dat3m.dartagnan.expression.IValue) FormulaManager(org.sosy_lab.java_smt.api.FormulaManager) BooleanFormulaManager(org.sosy_lab.java_smt.api.BooleanFormulaManager) Register(com.dat3m.dartagnan.program.Register) Event(com.dat3m.dartagnan.program.event.core.Event) BooleanFormula(org.sosy_lab.java_smt.api.BooleanFormula) Tuple(com.dat3m.dartagnan.wmm.utils.Tuple)

Example 28 with Tuple

use of com.dat3m.dartagnan.wmm.utils.Tuple in project Dat3M by hernanponcedeleon.

the class BasicRegRelation method mkTupleSets.

void mkTupleSets(Collection<Event> regReaders) {
    maxTupleSet = new TupleSet();
    minTupleSet = new TupleSet();
    ExecutionAnalysis exec = analysisContext.requires(ExecutionAnalysis.class);
    ImmutableMap<Register, ImmutableList<Event>> regWriterMap = task.getProgram().getCache().getRegWriterMap();
    for (Event regReader : regReaders) {
        for (Register register : getRegisters(regReader)) {
            List<Event> writers = regWriterMap.getOrDefault(register, ImmutableList.of());
            // =============== Reduce set of writes ==================
            // TODO: We assume that any Register-Write is always executed
            // if it is contained in the program flow
            // This may fail for RMWReadCond?! It seems to work fine for the litmus tests though.
            // =========================
            List<Event> possibleWriters = writers.stream().filter(x -> x.getCId() < regReader.getCId() && !exec.areMutuallyExclusive(x, regReader)).collect(Collectors.toList());
            List<Event> impliedWriters = possibleWriters.stream().filter(x -> exec.isImplied(regReader, x)).collect(Collectors.toList());
            if (!impliedWriters.isEmpty()) {
                Event lastImplied = impliedWriters.get(impliedWriters.size() - 1);
                possibleWriters.removeIf(x -> x.getCId() < lastImplied.getCId());
            }
            possibleWriters.removeIf(x -> possibleWriters.stream().anyMatch(y -> x.getCId() < y.getCId() && exec.isImplied(x, y)));
            // --- Min sets ---
            if (possibleWriters.size() == 1) {
                // there is only a single regWriter
                minTupleSet.add(new Tuple(possibleWriters.stream().findAny().get(), regReader));
            } else {
                // there are multiple regWriters, but some are exclusive to all others
                for (Event writer : possibleWriters) {
                    if (possibleWriters.stream().allMatch(x -> x == writer || exec.areMutuallyExclusive(x, writer))) {
                        minTupleSet.add(new Tuple(writer, regReader));
                    }
                }
            }
            // --- Max sets ---
            for (Event regWriter : possibleWriters) {
                maxTupleSet.add(new Tuple(regWriter, regReader));
            }
        }
    }
}
Also used : FormulaManager(org.sosy_lab.java_smt.api.FormulaManager) ImmutableMap(com.google.common.collect.ImmutableMap) ExecutionAnalysis(com.dat3m.dartagnan.program.analysis.ExecutionAnalysis) Collection(java.util.Collection) BooleanFormula(org.sosy_lab.java_smt.api.BooleanFormula) Set(java.util.Set) Collectors(java.util.stream.Collectors) BooleanFormulaManager(org.sosy_lab.java_smt.api.BooleanFormulaManager) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) TupleSet(com.dat3m.dartagnan.wmm.utils.TupleSet) SolverContext(org.sosy_lab.java_smt.api.SolverContext) IValue(com.dat3m.dartagnan.expression.IValue) Event(com.dat3m.dartagnan.program.event.core.Event) Tuple(com.dat3m.dartagnan.wmm.utils.Tuple) BigInteger(java.math.BigInteger) Register(com.dat3m.dartagnan.program.Register) RegWriter(com.dat3m.dartagnan.program.event.core.utils.RegWriter) StaticRelation(com.dat3m.dartagnan.wmm.relation.base.stat.StaticRelation) Utils.generalEqual(com.dat3m.dartagnan.expression.utils.Utils.generalEqual) TupleSet(com.dat3m.dartagnan.wmm.utils.TupleSet) ExecutionAnalysis(com.dat3m.dartagnan.program.analysis.ExecutionAnalysis) Register(com.dat3m.dartagnan.program.Register) ImmutableList(com.google.common.collect.ImmutableList) Event(com.dat3m.dartagnan.program.event.core.Event) Tuple(com.dat3m.dartagnan.wmm.utils.Tuple)

Example 29 with Tuple

use of com.dat3m.dartagnan.wmm.utils.Tuple 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);
}
Also used : Options(org.sosy_lab.common.configuration.Options) Property(com.dat3m.dartagnan.configuration.Property) Utils.intVar(com.dat3m.dartagnan.wmm.utils.Utils.intVar) BooleanFormula(org.sosy_lab.java_smt.api.BooleanFormula) Utils.edge(com.dat3m.dartagnan.wmm.utils.Utils.edge) HashMap(java.util.HashMap) Thread(com.dat3m.dartagnan.program.Thread) ArrayList(java.util.ArrayList) Wmm(com.dat3m.dartagnan.wmm.Wmm) Map(java.util.Map) SolverContext(org.sosy_lab.java_smt.api.SolverContext) Program(com.dat3m.dartagnan.program.Program) Tuple(com.dat3m.dartagnan.wmm.utils.Tuple) BigInteger(java.math.BigInteger) RelRf(com.dat3m.dartagnan.wmm.relation.base.memory.RelRf) FilterBasic(com.dat3m.dartagnan.program.filter.FilterBasic) EnumSet(java.util.EnumSet) InvalidConfigurationException(org.sosy_lab.common.configuration.InvalidConfigurationException) Utils.generalEqual(com.dat3m.dartagnan.expression.utils.Utils.generalEqual) AliasAnalysis(com.dat3m.dartagnan.program.analysis.AliasAnalysis) RelCo(com.dat3m.dartagnan.wmm.relation.base.memory.RelCo) Configuration(org.sosy_lab.common.configuration.Configuration) Collectors(java.util.stream.Collectors) Label(com.dat3m.dartagnan.program.event.core.Label) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) IntegerFormulaManager(org.sosy_lab.java_smt.api.IntegerFormulaManager) Tag(com.dat3m.dartagnan.program.event.Tag) BooleanFormulaManager(org.sosy_lab.java_smt.api.BooleanFormulaManager) Context(com.dat3m.dartagnan.verification.Context) RelationNameRepository(com.dat3m.dartagnan.wmm.relation.RelationNameRepository) List(java.util.List) Logger(org.apache.logging.log4j.Logger) Event(com.dat3m.dartagnan.program.event.core.Event) Preconditions(com.google.common.base.Preconditions) Load(com.dat3m.dartagnan.program.event.core.Load) LogManager(org.apache.logging.log4j.LogManager) FilterMinus(com.dat3m.dartagnan.program.filter.FilterMinus) Load(com.dat3m.dartagnan.program.event.core.Load) BooleanFormulaManager(org.sosy_lab.java_smt.api.BooleanFormulaManager) HashMap(java.util.HashMap) Label(com.dat3m.dartagnan.program.event.core.Label) ArrayList(java.util.ArrayList) Thread(com.dat3m.dartagnan.program.Thread) RelCo(com.dat3m.dartagnan.wmm.relation.base.memory.RelCo) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) Event(com.dat3m.dartagnan.program.event.core.Event) ArrayList(java.util.ArrayList) List(java.util.List) RelRf(com.dat3m.dartagnan.wmm.relation.base.memory.RelRf) BooleanFormula(org.sosy_lab.java_smt.api.BooleanFormula) Tuple(com.dat3m.dartagnan.wmm.utils.Tuple)

Example 30 with Tuple

use of com.dat3m.dartagnan.wmm.utils.Tuple in project Dat3M by hernanponcedeleon.

the class SymmetryEncoder method sort.

private void sort(List<Tuple> row) {
    if (!breakBySyncDegree) {
        // ===== Natural order =====
        row.sort(Comparator.naturalOrder());
        return;
    }
    // ====== Sync-degree based order ======
    // Setup of data structures
    Set<Event> inEvents = new HashSet<>();
    Set<Event> outEvents = new HashSet<>();
    for (Tuple t : row) {
        inEvents.add(t.getFirst());
        outEvents.add(t.getSecond());
    }
    Map<Event, Integer> combInDegree = new HashMap<>(inEvents.size());
    Map<Event, Integer> combOutDegree = new HashMap<>(outEvents.size());
    List<Axiom> axioms = memoryModel.getAxioms();
    for (Event e : inEvents) {
        int syncDeg = axioms.stream().mapToInt(ax -> ax.getRelation().getMinTupleSet().getBySecond(e).size() + 1).max().orElse(0);
        combInDegree.put(e, syncDeg);
    }
    for (Event e : outEvents) {
        int syncDec = axioms.stream().mapToInt(ax -> ax.getRelation().getMinTupleSet().getByFirst(e).size() + 1).max().orElse(0);
        combOutDegree.put(e, syncDec);
    }
    // Sort by sync degrees
    row.sort(Comparator.<Tuple>comparingInt(t -> combInDegree.get(t.getFirst()) * combOutDegree.get(t.getSecond())).reversed());
}
Also used : Event(com.dat3m.dartagnan.program.event.core.Event) Axiom(com.dat3m.dartagnan.wmm.axiom.Axiom) Tuple(com.dat3m.dartagnan.wmm.utils.Tuple)

Aggregations

Tuple (com.dat3m.dartagnan.wmm.utils.Tuple)52 TupleSet (com.dat3m.dartagnan.wmm.utils.TupleSet)37 Event (com.dat3m.dartagnan.program.event.core.Event)36 BooleanFormula (org.sosy_lab.java_smt.api.BooleanFormula)23 BooleanFormulaManager (org.sosy_lab.java_smt.api.BooleanFormulaManager)23 Thread (com.dat3m.dartagnan.program.Thread)13 ExecutionAnalysis (com.dat3m.dartagnan.program.analysis.ExecutionAnalysis)11 AliasAnalysis (com.dat3m.dartagnan.program.analysis.AliasAnalysis)10 Collectors (java.util.stream.Collectors)10 Tag (com.dat3m.dartagnan.program.event.Tag)9 MemEvent (com.dat3m.dartagnan.program.event.core.MemEvent)9 Relation (com.dat3m.dartagnan.wmm.relation.Relation)9 SolverContext (org.sosy_lab.java_smt.api.SolverContext)9 LogManager (org.apache.logging.log4j.LogManager)8 Logger (org.apache.logging.log4j.Logger)8 FilterBasic (com.dat3m.dartagnan.program.filter.FilterBasic)6 WmmAnalysis (com.dat3m.dartagnan.wmm.analysis.WmmAnalysis)5 java.util (java.util)5 Store (com.dat3m.dartagnan.program.event.core.Store)4 List (java.util.List)4