Skip to content

Commit

Permalink
Merged some files from kszi2/ic3-update
Browse files Browse the repository at this point in the history
  • Loading branch information
dantpu authored and leventeBajczi committed Nov 6, 2024
1 parent 13c6069 commit ef3de32
Show file tree
Hide file tree
Showing 7 changed files with 500 additions and 64 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright 2024 Budapest University of Technology and Economics
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package hu.bme.mit.theta.analysis.algorithm.bounded

import hu.bme.mit.theta.analysis.pred.PredPrec
import hu.bme.mit.theta.analysis.pred.PredState
import hu.bme.mit.theta.core.decl.Decl
import hu.bme.mit.theta.core.decl.Decls
import hu.bme.mit.theta.core.decl.VarDecl
import hu.bme.mit.theta.core.model.Valuation
import hu.bme.mit.theta.core.type.Expr
import hu.bme.mit.theta.core.type.anytype.Exprs
import hu.bme.mit.theta.core.type.booltype.BoolExprs
import hu.bme.mit.theta.core.type.booltype.BoolLitExpr
import hu.bme.mit.theta.core.type.booltype.BoolType
import hu.bme.mit.theta.core.type.booltype.IffExpr
import hu.bme.mit.theta.core.type.booltype.SmartBoolExprs.And
import hu.bme.mit.theta.core.type.booltype.SmartBoolExprs.Not
import hu.bme.mit.theta.core.utils.ExprUtils
import hu.bme.mit.theta.core.utils.indexings.VarIndexingFactory
import java.util.HashMap

fun MonolithicExpr.createAbstract(prec: PredPrec): MonolithicExpr {
// TODO: handle initOffsetIndex in abstract initExpr
val lambdaList = ArrayList<IffExpr>()
val lambdaPrimeList = ArrayList<IffExpr>()
val activationLiterals = ArrayList<VarDecl<*>>()
val literalToPred = HashMap<Decl<*>, Expr<BoolType>>()

prec.preds.forEachIndexed { index, expr ->
run {
val v = Decls.Var("v$index", BoolType.getInstance())
activationLiterals.add(v)
literalToPred[v] = expr
lambdaList.add(IffExpr.of(v.ref, expr))
lambdaPrimeList.add(
BoolExprs.Iff(Exprs.Prime(v.ref), ExprUtils.applyPrimes(expr, this.transOffsetIndex))
)
}
}

var indexingBuilder = VarIndexingFactory.indexingBuilder(1)
this.vars./*filter { it !in ctrlVars }.*/ forEach { decl ->
repeat(transOffsetIndex.get(decl)) { indexingBuilder = indexingBuilder.inc(decl) }
}

return MonolithicExpr(
initExpr = And(And(lambdaList), initExpr),
transExpr = And(And(lambdaList), And(lambdaPrimeList), transExpr),
propExpr = Not(And(And(lambdaList), Not(propExpr))),
transOffsetIndex = indexingBuilder.build(),
initOffsetIndex = VarIndexingFactory.indexing(0),
vars = activationLiterals /* + ctrlVars*/,
valToState = { valuation: Valuation ->
PredState.of(
valuation
.toMap()
.entries
.stream()
.map {
when ((it.value as BoolLitExpr).value) {
true -> literalToPred[it.key]
false -> Not(literalToPred[it.key])
}
}
.toList()
)
},
biValToAction = this.biValToAction,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,34 @@
*/
package hu.bme.mit.theta.analysis.algorithm.bounded

import hu.bme.mit.theta.analysis.expl.ExplState
import hu.bme.mit.theta.analysis.expr.ExprAction
import hu.bme.mit.theta.analysis.expr.ExprState
import hu.bme.mit.theta.core.decl.VarDecl
import hu.bme.mit.theta.core.model.Valuation
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.getVars
import hu.bme.mit.theta.core.utils.indexings.VarIndexing
import hu.bme.mit.theta.core.utils.indexings.VarIndexingFactory

data class MonolithicExpr(
data class MonolithicExpr
@JvmOverloads
constructor(
val initExpr: Expr<BoolType>,
val transExpr: Expr<BoolType>,
val propExpr: Expr<BoolType>,
val transOffsetIndex: VarIndexing = VarIndexingFactory.indexing(1),
val initOffsetIndex: VarIndexing = VarIndexingFactory.indexing(0),
val vars: List<VarDecl<*>> =
(getVars(initExpr) union getVars(transExpr) union getVars(propExpr)).toList(),
val valToState: (Valuation) -> ExprState = ExplState::of,
val biValToAction: (Valuation, Valuation) -> ExprAction = { _: Valuation, _: Valuation ->
object : ExprAction {
override fun toExpr(): Expr<BoolType> = transExpr

override fun nextIndexing(): VarIndexing = transOffsetIndex
}
},
val ctrlVars: Collection<VarDecl<*>> = listOf(),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*
* Copyright 2024 Budapest University of Technology and Economics
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package hu.bme.mit.theta.analysis.algorithm.bounded;

import static hu.bme.mit.theta.core.type.booltype.SmartBoolExprs.Not;

import com.google.common.base.Preconditions;
import hu.bme.mit.theta.analysis.*;
import hu.bme.mit.theta.analysis.algorithm.SafetyChecker;
import hu.bme.mit.theta.analysis.algorithm.SafetyResult;
import hu.bme.mit.theta.analysis.algorithm.Witness;
import hu.bme.mit.theta.analysis.expr.ExprAction;
import hu.bme.mit.theta.analysis.expr.ExprState;
import hu.bme.mit.theta.analysis.expr.refinement.ExprTraceChecker;
import hu.bme.mit.theta.analysis.expr.refinement.ExprTraceFwBinItpChecker;
import hu.bme.mit.theta.analysis.expr.refinement.ExprTraceStatus;
import hu.bme.mit.theta.analysis.expr.refinement.ItpRefutation;
import hu.bme.mit.theta.analysis.pred.PredPrec;
import hu.bme.mit.theta.analysis.unit.UnitPrec;
import hu.bme.mit.theta.common.logging.Logger;
import hu.bme.mit.theta.core.model.Valuation;
import hu.bme.mit.theta.solver.SolverFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;

public class MonolithicExprCegarChecker<
W extends Witness, S extends ExprState, A extends ExprAction, P extends Prec>
implements SafetyChecker<W, Trace<S, A>, PredPrec> {
private final MonolithicExpr model;
private final Function<
MonolithicExpr,
SafetyChecker<
W,
? extends Trace<? extends ExprState, ? extends ExprAction>,
UnitPrec>>
checkerFactory;

private final Function<Valuation, S> valToState;
private final BiFunction<Valuation, Valuation, A> biValToAction;

private final SolverFactory solverFactory;

private final Logger logger;

public MonolithicExprCegarChecker(
MonolithicExpr model,
Function<
MonolithicExpr,
SafetyChecker<
W,
? extends Trace<? extends ExprState, ? extends ExprAction>,
UnitPrec>>
checkerFactory,
Function<Valuation, S> valToState,
BiFunction<Valuation, Valuation, A> biValToAction,
Logger logger,
SolverFactory solverFactory) {
this.model = model;
this.checkerFactory = checkerFactory;
this.valToState = valToState;
this.biValToAction = biValToAction;
this.logger = logger;
this.solverFactory = solverFactory;
}

public SafetyResult<W, Trace<S, A>> check(PredPrec initPrec) {
var predPrec =
initPrec == null
? PredPrec.of(List.of(model.getInitExpr(), model.getPropExpr()))
: initPrec;

while (true) {
final var abstractMonolithicExpr =
AbstractMonolithicExprKt.createAbstract(model, predPrec);
final var checker = checkerFactory.apply(abstractMonolithicExpr);

final var result = checker.check();
if (result.isSafe()) {
logger.write(Logger.Level.INFO, "Model is safe, stopping CEGAR");
return SafetyResult.safe(result.getWitness());
} else {
Preconditions.checkState(result.isUnsafe());
final Trace<? extends ExprState, ? extends ExprAction> trace =
result.asUnsafe().getCex();

final ExprTraceChecker<ItpRefutation> exprTraceFwBinItpChecker =
ExprTraceFwBinItpChecker.create(
model.getInitExpr(),
Not(model.getPropExpr()),
solverFactory.createItpSolver());

if (trace != null) {
final ExprTraceStatus<ItpRefutation> concretizationResult =
exprTraceFwBinItpChecker.check(trace);
if (concretizationResult.isFeasible()) {
logger.write(Logger.Level.INFO, "Model is unsafe, stopping CEGAR");

final var valTrace = concretizationResult.asFeasible().getValuations();
Valuation lastValuation = null;
final ArrayList<S> states = new ArrayList<>();
final ArrayList<A> actions = new ArrayList<>();
for (var val : valTrace.getStates()) {
states.add(valToState.apply(val));
if (lastValuation != null) {
actions.add(biValToAction.apply(lastValuation, val));
}
lastValuation = val;
}

return SafetyResult.unsafe(Trace.of(states, actions), result.getWitness());
} else {
final var ref = concretizationResult.asInfeasible().getRefutation();
final var newPred = ref.get(ref.getPruneIndex());
final var newPrec = PredPrec.of(newPred);
predPrec = predPrec.join(newPrec);
logger.write(Logger.Level.INFO, "Added new predicate " + newPrec);
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2024 Budapest University of Technology and Economics
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package hu.bme.mit.theta.analysis.algorithm.bounded

import hu.bme.mit.theta.core.type.booltype.BoolExprs.Not
import hu.bme.mit.theta.core.utils.ExprUtils
import hu.bme.mit.theta.core.utils.indexings.VarIndexingFactory

fun MonolithicExpr.createReversed(): MonolithicExpr {
return MonolithicExpr(
initExpr = Not(propExpr),
transExpr = ExprUtils.reverse(transExpr, transOffsetIndex),
propExpr = Not(initExpr),
transOffsetIndex = transOffsetIndex,
initOffsetIndex = VarIndexingFactory.indexing(0),
vars = vars,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,23 @@
*/
package hu.bme.mit.theta.core.type.anytype;

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

import hu.bme.mit.theta.core.decl.Decl;
import hu.bme.mit.theta.core.type.Expr;
import hu.bme.mit.theta.core.type.Type;
import hu.bme.mit.theta.core.type.booltype.BoolType;

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

public final class Exprs {

private Exprs() {
}
private Exprs() {}

public static <DeclType extends Type> RefExpr<DeclType> Ref(final Decl<DeclType> decl) {
return RefExpr.of(decl);
}

public static <ExprType extends Type> IteExpr<ExprType> Ite(final Expr<BoolType> cond,
final Expr<ExprType> then,
final Expr<ExprType> elze) {
public static <ExprType extends Type> IteExpr<ExprType> Ite(
final Expr<BoolType> cond, final Expr<ExprType> then, final Expr<ExprType> elze) {
return IteExpr.of(cond, then, elze);
}

Expand All @@ -42,27 +40,29 @@ public static <ExprType extends Type> PrimeExpr<ExprType> Prime(final Expr<ExprT
}

public static <ArrType extends Type, OffsetType extends Type, ExprType extends Type>
Dereference<ArrType, OffsetType, ExprType> Dereference(final Expr<ArrType> arr, final Expr<OffsetType> offset, final ExprType type) {
Dereference<ArrType, OffsetType, ExprType> Dereference(
final Expr<ArrType> arr, final Expr<OffsetType> offset, final ExprType type) {
return Dereference.of(arr, offset, type);
}

public static <ArrType extends Type, ExprType extends Type>
Reference<ArrType, ExprType> Reference(final Expr<ExprType> expr, final ArrType type) {
Reference<ArrType, ExprType> Reference(final Expr<ExprType> expr, final ArrType type) {
return Reference.of(expr, type);
}

/*
* Convenience methods
*/

public static <ExprType extends Type> PrimeExpr<ExprType> Prime(final Expr<ExprType> op,
final int i) {
checkArgument(i > 0);
if (i == 1) {
public static <ExprType extends Type> Expr<ExprType> Prime(
final Expr<ExprType> op, final int i) {
checkArgument(i >= 0);
if (i == 0) {
return op;
} else if (i == 1) {
return Prime(op);
} else {
return Prime(Prime(op, i - 1));
}
}

}
Loading

0 comments on commit ef3de32

Please sign in to comment.