Skip to content

Commit

Permalink
Merge pull request #99 from ftsrg/xsts-dev
Browse files Browse the repository at this point in the history
xsts-dev
  • Loading branch information
hajduakos authored Jan 31, 2021
2 parents 0f1a328 + 5980642 commit 1509563
Show file tree
Hide file tree
Showing 35 changed files with 36,882 additions and 107 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Currently, the following tools are available (follow the links for more informat
* [`theta-xta-cli`](subprojects/xta-cli): Verification of [Uppaal](http://www.uppaal.org/) timed automata (XTA).
* [`theta-xsts-cli`](subprojects/xsts-cli): Verification of safety properties in eXtended Symbolic Transition Systems (XSTS) using CEGAR-based algorithms.
* [Gamma](https://github.com/ftsrg/gamma) is a statechart composition framework, that supports theta-xsts-cli as a backend to verify collaborating state machines.
* theta-xsts-cli natively supports Petri net models in the [PNML](http://www.pnml.org/) format (experimental).

## Overview of the architecture

Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ buildscript {

allprojects {
group = "hu.bme.mit.inf.theta"
version = "2.8.0"
version = "2.9.0"

apply(from = rootDir.resolve("gradle/shared-with-buildSrc/mirrors.gradle.kts"))
}
Expand Down
8 changes: 7 additions & 1 deletion doc/CEGAR-algorithms.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ The domain controls the abstract information that is being tracked about the sys
* `PRED_SPLIT`: Boolean predicate abstraction, but states are [split]((https://link.springer.com/content/pdf/10.1007%2Fs10817-019-09535-x.pdf)) into sub-states along disjunctions.
* `EXPL`: [Explicit-value abstraction]((https://link.springer.com/chapter/10.1007/978-3-642-37057-1_11)) keeps track of concrete values, but only for a (continuously expanded) set of variables.
* `PROD`: Product abstraction, available for XSTS models. The set of control variables (marked with `ctrl`) are tracked explicitly while others are tracked by predicates.
* `PROD_AUTO`: Automatic product abstraction, available for XSTS models. The set of control variables (marked with `ctrl`) are tracked explicitly. Other variables are also tracked explicitly if they appear in a given number of predicates (defined with the `--maxpredcount` option).

Predicate abstraction (`PRED_*`) tracks logical formulas instead of concrete values of variables, which can be efficient for variables with large (or infinite) domain.
Explicit-values (`EXPL`) keep track of a subset of system variables, which can be efficient if variables are mostly deterministic or have a small domain.
Expand All @@ -54,7 +55,7 @@ More information on the abstract domains can be found in Section 2.2.1 and 3.1.3
Controls the initial precision of the abstraction (e.g., what predicates or variables are tracked initially).

* `EMPTY`: Start with an empty initial precision.
* `ALLVARS`: Tracks all variables from the beginning. Available for CFA if `--domain` is `EXPL`.
* `ALLVARS`: Tracks all variables from the beginning. Available for CFA and XSTS if `--domain` is `EXPL`.
* `ALLASSUMES`: Track all assumptions by default (e.g., branch/loop conditions). Only applicable for CFA and if `--domain` is `PRED_*`.
* `PROP`: Available for XSTS. Tracks variables from the property if `--domain` is `EXPL` and predicates from the property if `--domain` is `PRED_*`.
* `CTRL`: Available for XSTS if `--domain` is `PROD` or `EXPL`. Tracks all control variables.
Expand Down Expand Up @@ -89,6 +90,11 @@ If the limit is exceeded, unknown values are propagated.
As a special case, `0` stands for infinite, but it should only be used if the model does not have any variable with unbounded domain (or that variable is deterministically assigned).
In general, values between `5` to `50` perform well (see Section 3.1.1 of [our JAR paper](https://link.springer.com/content/pdf/10.1007%2Fs10817-019-09535-x.pdf) for more information).

### `--maxpredcount`

Available for XSTS.
The number of predicates a variable has to appear in before it is tracked explicitly when the `PRED_AUTO` domain is used.

### `--refinement`

Strategy for refining the precision of the abstraction, i.e., inferring new predicates or variables to be tracked.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,16 +189,16 @@ private static ApplyResult applyNonDet(final NonDetStmt stmt, final MutableValua
return apply(stmt.getStmts().get(successIndex), val, approximate);
} else if (approximate) {
apply(stmt.getStmts().get(successIndex), val, approximate);
List<Decl> toRemove = new ArrayList<Decl>();
for (Decl decl : val.getDecls()) {
List<Decl<?>> toRemove = new ArrayList<Decl<?>>();
for (Decl<?> decl : val.getDecls()) {
for (MutableValuation subVal : valuations) {
if (!val.eval(decl).equals(subVal.eval(decl))) {
toRemove.add(decl);
break;
}
}
}
for (Decl decl : toRemove) val.remove(decl);
for (Decl<?> decl : toRemove) val.remove(decl);
return ApplyResult.SUCCESS;
} else {
return ApplyResult.FAILURE;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package hu.bme.mit.theta.analysis.prod2.prod2explpred;

import hu.bme.mit.theta.analysis.expl.ExplPrec;
import hu.bme.mit.theta.analysis.expr.refinement.ItpRefutation;
import hu.bme.mit.theta.analysis.expr.refinement.RefutationToPrec;
import hu.bme.mit.theta.analysis.pred.ExprSplitters.ExprSplitter;
import hu.bme.mit.theta.analysis.pred.PredPrec;
import hu.bme.mit.theta.analysis.prod2.Prod2Prec;
import hu.bme.mit.theta.core.decl.VarDecl;
import hu.bme.mit.theta.core.type.Expr;
import hu.bme.mit.theta.core.type.booltype.BoolType;
import hu.bme.mit.theta.core.utils.ExprUtils;

import java.util.*;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

public final class AutomaticItpRefToProd2ExplPredPrec implements RefutationToPrec<Prod2Prec<ExplPrec, PredPrec>, ItpRefutation> {

private final Set<VarDecl<?>> explPreferredVars;
private final Map<VarDecl<?>, Integer> predCount;
private final ExprSplitter exprSplitter;
private final int maxPredCount;

private AutomaticItpRefToProd2ExplPredPrec(final Set<VarDecl<?>> explPreferredVars, final ExprSplitter exprSplitter, final int maxPredCount) {
this.explPreferredVars = checkNotNull(explPreferredVars);
this.exprSplitter = checkNotNull(exprSplitter);
this.maxPredCount = maxPredCount;

this.predCount = new HashMap<>();
}

public static AutomaticItpRefToProd2ExplPredPrec create(final Set<VarDecl<?>> explPreferredVars, final ExprSplitter exprSplitter, final int maxPredCount) {
checkArgument(maxPredCount >= 0, "MaxPredCount must be non-negative.");
return new AutomaticItpRefToProd2ExplPredPrec(explPreferredVars, exprSplitter, maxPredCount);
}

@Override
public Prod2Prec<ExplPrec, PredPrec> toPrec(ItpRefutation refutation, int index) {
final Collection<Expr<BoolType>> exprs = exprSplitter.apply(refutation.get(index));
Set<VarDecl<?>> explSelectedVars = new HashSet<>();
Set<Expr<BoolType>> predSelectedExprs = new HashSet<>();
for (var expr : exprs) {
final Set<VarDecl<?>> containedVars = ExprUtils.getVars(expr);
boolean allExpl = true;
for (var decl : containedVars) {
if(maxPredCount>=0){
if (!predCount.containsKey(decl)) {
predCount.put(decl, 1);
}
if(predCount.get(decl)>=maxPredCount){
explPreferredVars.add(decl);
} else {
predCount.put(decl, predCount.get(decl) + 1);
}
}
if (explPreferredVars.contains(decl)) {
explSelectedVars.add(decl);
} else allExpl = false;
}
if (!allExpl) predSelectedExprs.add(expr);
}
return Prod2Prec.of(ExplPrec.of(explSelectedVars), PredPrec.of(predSelectedExprs));

}

@Override
public Prod2Prec<ExplPrec, PredPrec> join(Prod2Prec<ExplPrec, PredPrec> prec1, Prod2Prec<ExplPrec, PredPrec> prec2) {
return Prod2Prec.of(prec1.getPrec1().join(prec2.getPrec1()), prec1.getPrec2().join(prec2.getPrec2()));
}

@Override
public String toString() {
return getClass().getSimpleName();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package hu.bme.mit.theta.core.stmt;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import hu.bme.mit.theta.common.Utils;

import java.util.List;
Expand All @@ -14,8 +16,8 @@ public final class NonDetStmt implements Stmt {
private volatile int hashCode = 0;

private NonDetStmt(final List<Stmt> stmts) {
this.stmts = stmts;
if (stmts.isEmpty()) stmts.add(SkipStmt.getInstance());
if (stmts.isEmpty()) this.stmts= ImmutableList.of(SkipStmt.getInstance());
else this.stmts = stmts;
}

public static NonDetStmt of(final List<Stmt> stmts) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package hu.bme.mit.theta.core.stmt;

import com.google.common.collect.ImmutableList;
import hu.bme.mit.theta.common.Utils;

import java.util.List;
Expand All @@ -14,8 +15,8 @@ public final class OrtStmt implements Stmt {
private volatile int hashCode = 0;

private OrtStmt(final List<Stmt> stmts) {
this.stmts = stmts;
if (stmts.isEmpty()) stmts.add(SkipStmt.getInstance());
if (stmts.isEmpty()) this.stmts= ImmutableList.of(SkipStmt.getInstance());
else this.stmts = stmts;
}

public static OrtStmt of(final List<Stmt> stmts) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package hu.bme.mit.theta.core.stmt;

import com.google.common.collect.ImmutableList;
import hu.bme.mit.theta.common.Utils;

import java.util.List;
Expand All @@ -13,8 +14,8 @@ public final class SequenceStmt implements Stmt {
private volatile int hashCode = 0;

private SequenceStmt(final List<Stmt> stmts) {
this.stmts = stmts;
if (stmts.isEmpty()) stmts.add(SkipStmt.getInstance());
if (stmts.isEmpty()) this.stmts= ImmutableList.of(SkipStmt.getInstance());
else this.stmts = stmts;
}

public static SequenceStmt of(final List<Stmt> stmts) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package hu.bme.mit.theta.core.utils;

import hu.bme.mit.theta.core.stmt.*;
import hu.bme.mit.theta.core.type.Type;

public class StmtCounterVisitor implements StmtVisitor<Void, Integer> {

private static final class LazyHolder {
private final static StmtCounterVisitor INSTANCE = new StmtCounterVisitor();
}

private StmtCounterVisitor() {
}

public static StmtCounterVisitor getInstance() {
return StmtCounterVisitor.LazyHolder.INSTANCE;
}

@Override
public Integer visit(SkipStmt stmt, Void param) {
return 1;
}

@Override
public Integer visit(AssumeStmt stmt, Void param) {
return 1;
}

@Override
public <DeclType extends Type> Integer visit(AssignStmt<DeclType> stmt, Void param) {
return 1;
}

@Override
public <DeclType extends Type> Integer visit(HavocStmt<DeclType> stmt, Void param) {
return 1;
}

@Override
public Integer visit(SequenceStmt stmt, Void param) {
int count = 0;
for (var subStmt: stmt.getStmts()){
count+=subStmt.accept(this,null);
}
return count+1;
}

@Override
public Integer visit(NonDetStmt stmt, Void param) {
int count = 0;
for (var subStmt: stmt.getStmts()){
count+=subStmt.accept(this,null);
}
return count+1;
}

@Override
public Integer visit(OrtStmt stmt, Void param) {
int count = 0;
for (var subStmt: stmt.getStmts()){
count+=subStmt.accept(this,null);
}
return count+1;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ public StmtUnfoldResult visit(SequenceStmt sequenceStmt, VarIndexing indexing) {
@Override
public StmtUnfoldResult visit(NonDetStmt nonDetStmt, VarIndexing indexing) {

List<Expr<BoolType>> choices = new ArrayList<Expr<BoolType>>();
List<VarIndexing> indexings = new ArrayList<VarIndexing>();
List<Expr<BoolType>> choices = new ArrayList<>();
List<VarIndexing> indexings = new ArrayList<>();
VarIndexing jointIndexing = indexing;
int count = 0;
VarDecl<IntType> tempVar = VarPoolUtil.requestInt();
Expand All @@ -126,11 +126,11 @@ public StmtUnfoldResult visit(NonDetStmt nonDetStmt, VarIndexing indexing) {
jointIndexing = jointIndexing.join(result.indexing);
}
Set<VarDecl<?>> vars = ExprUtils.getVars(choices);
List<Expr<BoolType>> branchExprs = new ArrayList<Expr<BoolType>>();
List<Expr<BoolType>> branchExprs = new ArrayList<>();
for (int i = 0; i < choices.size(); i++) {
List<Expr<BoolType>> exprs = new ArrayList<Expr<BoolType>>();
List<Expr<BoolType>> exprs = new ArrayList<>();
exprs.add(choices.get(i));
for (VarDecl decl : vars) {
for (VarDecl<?> decl : vars) {
int currentBranchIndex = indexings.get(i).get(decl);
int jointIndex = jointIndexing.get(decl);
if (currentBranchIndex < jointIndex) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ private VarPoolUtil() {}
private static ArrayDeque<VarDecl<IntType>> intPool=new ArrayDeque<VarDecl<IntType>>();
private static int counter=0;

public static VarDecl requestInt(){
public static VarDecl<IntType> requestInt(){
if(intPool.isEmpty()) return Decls.Var("temp"+counter++,Int());
else return intPool.remove();
}
Expand Down
Loading

0 comments on commit 1509563

Please sign in to comment.