Skip to content

Commit 86258a6

Browse files
Merge pull request #379 from ftsrg/xcfa-mdd-trace
XCFA MDD Trace
2 parents e86bd9f + d1b2ddf commit 86258a6

File tree

6 files changed

+79
-19
lines changed

6 files changed

+79
-19
lines changed

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ buildscript {
2929

3030
allprojects {
3131
group = "hu.bme.mit.theta"
32-
version = "6.17.0"
32+
version = "6.17.1"
3333

3434

3535
apply(from = rootDir.resolve("gradle/shared-with-buildSrc/mirrors.gradle.kts"))

subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/bounded/MonolithicExprCegarChecker.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import hu.bme.mit.theta.analysis.unit.UnitPrec;
3333
import hu.bme.mit.theta.common.logging.Logger;
3434
import hu.bme.mit.theta.solver.SolverFactory;
35+
import java.util.ArrayList;
3536
import java.util.List;
3637
import java.util.function.Function;
3738

@@ -103,7 +104,21 @@ public MonolithicExprCegarChecker(
103104
if (concretizationResult.isFeasible()) {
104105
logger.write(Logger.Level.MAINSTEP, "Model is unsafe, stopping CEGAR\n");
105106

106-
return SafetyResult.unsafe(trace, result.getProof());
107+
final var valuations =
108+
concretizationResult.asFeasible().getValuations().getStates();
109+
final List<ExprState> states = new ArrayList<>();
110+
final List<ExprAction> actions = new ArrayList<>();
111+
for (int i = 0; i < valuations.size(); ++i) {
112+
states.add(model.getValToState().invoke(valuations.get(i)));
113+
if (i > 0) {
114+
actions.add(
115+
model.getBiValToAction()
116+
.invoke(valuations.get(i - 1), valuations.get(i)));
117+
}
118+
}
119+
120+
return SafetyResult.Unsafe.unsafe(
121+
Trace.of(states, actions), result.getProof());
107122
} else {
108123
final var ref = concretizationResult.asInfeasible().getRefutation();
109124
final var newPred = ref.get(ref.getPruneIndex());

subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mdd/MddChecker.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,6 @@ public SafetyResult<MddProof, Trace<S, A>> check(UnitPrec prec) {
283283
} else {
284284
result = SafetyResult.safe(MddProof.of(stateSpace), statistics);
285285
}
286-
logger.write(Level.RESULT, "%s\n", result);
287286
return result;
288287
}
289288
}

subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToMddChecker.kt

Lines changed: 59 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,21 @@ package hu.bme.mit.theta.xcfa.cli.checkers
1818
import hu.bme.mit.theta.analysis.Trace
1919
import hu.bme.mit.theta.analysis.algorithm.SafetyChecker
2020
import hu.bme.mit.theta.analysis.algorithm.SafetyResult
21+
import hu.bme.mit.theta.analysis.algorithm.bounded.MonolithicExpr
22+
import hu.bme.mit.theta.analysis.algorithm.bounded.MonolithicExprCegarChecker
2123
import hu.bme.mit.theta.analysis.algorithm.bounded.createMonolithicL2S
2224
import hu.bme.mit.theta.analysis.algorithm.bounded.createReversed
2325
import hu.bme.mit.theta.analysis.algorithm.mdd.MddChecker
26+
import hu.bme.mit.theta.analysis.algorithm.mdd.MddProof
2427
import hu.bme.mit.theta.analysis.algorithm.mdd.MddValuationCollector
2528
import hu.bme.mit.theta.analysis.algorithm.mdd.varordering.orderVarsFromRandomStartingPoints
2629
import hu.bme.mit.theta.analysis.expl.ExplState
2730
import hu.bme.mit.theta.analysis.expr.ExprAction
2831
import hu.bme.mit.theta.analysis.expr.ExprState
32+
import hu.bme.mit.theta.analysis.pred.PredPrec
33+
import hu.bme.mit.theta.analysis.pred.PredState
34+
import hu.bme.mit.theta.analysis.ptr.PtrPrec
35+
import hu.bme.mit.theta.analysis.ptr.PtrState
2936
import hu.bme.mit.theta.analysis.unit.UnitPrec
3037
import hu.bme.mit.theta.common.logging.Logger
3138
import hu.bme.mit.theta.core.decl.IndexedConstDecl
@@ -68,33 +75,71 @@ fun getMddChecker(
6875
it.copy(propExpr = True()).createMonolithicL2S()
6976
else it
7077
}
71-
.let {
72-
if (mddConfig.cegar) {
73-
TODO("MDD cannot return traces, and thus, --cegar won't work yet.")
74-
} else it
75-
}
7678
.let { if (mddConfig.reversed) it.createReversed() else it }
7779

7880
val stmts =
7981
xcfa.procedures
8082
.flatMap { it.edges.flatMap { xcfaEdge -> xcfaEdge.getFlatLabels().map { it.toStmt() } } }
8183
.toSet()
82-
val variableOrder = orderVarsFromRandomStartingPoints(monolithicExpr.vars, stmts, 20)
8384
val solverPool = SolverPool(refinementSolverFactory)
8485
val iterationStrategy = mddConfig.iterationStrategy
8586

86-
val checker =
87-
MddChecker.create<ExprState, ExprAction>(
88-
monolithicExpr,
89-
variableOrder,
87+
val baseChecker = { abstractME: MonolithicExpr ->
88+
MddChecker.create(
89+
abstractME,
90+
orderVarsFromRandomStartingPoints(abstractME.vars, stmts, 20),
9091
solverPool,
9192
logger,
9293
iterationStrategy,
93-
monolithicExpr.valToState,
94-
monolithicExpr.biValToAction,
94+
abstractME.valToState,
95+
abstractME.biValToAction,
9596
)
96-
return SafetyChecker<LocationInvariants, Trace<ExprState, ExprAction>, UnitPrec> { input ->
97-
val result = checker.check(input)
97+
}
98+
99+
val checker: SafetyChecker<MddProof, Trace<ExprState, ExprAction>, UnitPrec> =
100+
(if (mddConfig.cegar) {
101+
val cegarChecker =
102+
MonolithicExprCegarChecker(
103+
monolithicExpr,
104+
baseChecker,
105+
logger,
106+
getSolver(mddConfig.solver, false),
107+
)
108+
object :
109+
SafetyChecker<
110+
MddProof,
111+
Trace<XcfaState<PtrState<PredState>>, XcfaAction>,
112+
XcfaPrec<PtrPrec<PredPrec>>,
113+
> {
114+
override fun check(
115+
initPrec: XcfaPrec<PtrPrec<PredPrec>>
116+
): SafetyResult<MddProof, Trace<XcfaState<PtrState<PredState>>, XcfaAction>> {
117+
val result =
118+
cegarChecker.check(initPrec.p.innerPrec) // states are PredState, actions are XcfaAction
119+
if (result.isUnsafe) {
120+
val cex = result.asUnsafe().cex as Trace<PredState, XcfaAction>
121+
val locs =
122+
(0 until cex.length()).map { i -> cex.actions[i].source } +
123+
cex.actions[cex.length() - 1].target
124+
val states = locs.mapIndexed { i, it -> XcfaState(xcfa, it, PtrState(cex.states[i])) }
125+
return SafetyResult.unsafe(Trace.of(states, cex.actions), result.proof)
126+
} else
127+
return result
128+
as SafetyResult<MddProof, Trace<XcfaState<PtrState<PredState>>, XcfaAction>>
129+
}
130+
131+
override fun check():
132+
SafetyResult<MddProof, Trace<XcfaState<PtrState<PredState>>, XcfaAction>> {
133+
return check(mddConfig.initPrec.predPrec(xcfa))
134+
}
135+
}
136+
} else {
137+
baseChecker(monolithicExpr)
138+
})
139+
as SafetyChecker<MddProof, Trace<ExprState, ExprAction>, UnitPrec>
140+
141+
return SafetyChecker<LocationInvariants, Trace<ExprState, ExprAction>, UnitPrec> {
142+
val result = checker.check()
98143
if (result.isUnsafe) {
99144
SafetyResult.unsafe(result.asUnsafe().cex, LocationInvariants())
100145
} else {

subprojects/xcfa/xcfa-cli/src/test/resources/c/litmustest/singlethread/22nondet.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
void reach_error(){}
2-
extern int __VERIFIER_nondet_int();
2+
extern char __VERIFIER_nondet_char();
33
int main() {
44
int i = 0;
5-
if(__VERIFIER_nondet_int() % 2) {
5+
if(__VERIFIER_nondet_char() % 2) {
66
i = 1;
77
} else {
88
i = 2;

subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/XcfaToC.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ fun XCFA.toC(
6565
"""
6666
extern void abort();
6767
extern unsigned short __VERIFIER_nondet_ushort();
68+
extern char __VERIFIER_nondet_char();
6869
extern short __VERIFIER_nondet_short();
6970
extern int __VERIFIER_nondet_int();
7071
extern _Bool __VERIFIER_nondet__Bool();

0 commit comments

Comments
 (0)