Skip to content

Commit

Permalink
Merge pull request #118 from ftsrg/xsts-loops
Browse files Browse the repository at this point in the history
Combined prod domain
  • Loading branch information
mondokm authored Jun 18, 2021
2 parents 8285662 + 94c30a3 commit 202f3c0
Show file tree
Hide file tree
Showing 25 changed files with 1,825 additions and 94 deletions.
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.14.1"
version = "2.15.0"

apply(from = rootDir.resolve("gradle/shared-with-buildSrc/mirrors.gradle.kts"))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package hu.bme.mit.theta.analysis.expr.refinement.maxatomcount;

import hu.bme.mit.theta.core.decl.VarDecl;

import java.util.Map;

public class IndividualMaxAtomCount implements MaxAtomCount{
private Map<VarDecl<?>,Integer> declToCount;

public IndividualMaxAtomCount(final Map<VarDecl<?>,Integer> declToCount){
this.declToCount = declToCount;
}

@Override
public int get(VarDecl<?> decl) {
return declToCount.get(decl);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package hu.bme.mit.theta.analysis.expr.refinement.maxatomcount;

import hu.bme.mit.theta.core.decl.VarDecl;

public interface MaxAtomCount {

int get(final VarDecl<?> decl);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package hu.bme.mit.theta.analysis.expr.refinement.maxatomcount;

import hu.bme.mit.theta.core.decl.VarDecl;

public class NMaxAtomCount implements MaxAtomCount{

private final int n;

public NMaxAtomCount(final int n){
this.n=n;
}

@Override
public int get(VarDecl<?> decl) {
return n;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package hu.bme.mit.theta.analysis.expr.refinement.maxatomcount;

import hu.bme.mit.theta.core.decl.VarDecl;

public class UnlimitedMaxAtomCount implements MaxAtomCount {

@Override
public int get(VarDecl<?> decl) {
return 0;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import hu.bme.mit.theta.analysis.Prec;
import hu.bme.mit.theta.analysis.State;

final class Prod2InitFunc<S1 extends State, S2 extends State, P1 extends Prec, P2 extends Prec>
public final class Prod2InitFunc<S1 extends State, S2 extends State, P1 extends Prec, P2 extends Prec>
implements InitFunc<Prod2State<S1, S2>, Prod2Prec<P1, P2>> {

private final InitFunc<S1, P1> initFunc1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import hu.bme.mit.theta.analysis.PartialOrd;
import hu.bme.mit.theta.analysis.State;

final class Prod2Ord<S1 extends State, S2 extends State> implements PartialOrd<Prod2State<S1, S2>> {
public final class Prod2Ord<S1 extends State, S2 extends State> implements PartialOrd<Prod2State<S1, S2>> {

private final PartialOrd<S1> partialOrd1;
private final PartialOrd<S2> partialOrd2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

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.maxatomcount.MaxAtomCount;
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.common.container.Containers;
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;
Expand All @@ -21,61 +23,57 @@
public final class AutomaticItpRefToProd2ExplPredPrec implements RefutationToPrec<Prod2Prec<ExplPrec, PredPrec>, ItpRefutation> {

private final Set<VarDecl<?>> explPreferredVars;
private final Map<VarDecl<?>, Integer> predCount;
private final Map<VarDecl<?>, Set<Expr<BoolType>>> atomCount;
private final ExprSplitter exprSplitter;
private final int maxPredCount;
private final MaxAtomCount maxAtomCount;

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

this.predCount = new LinkedHashMap<>();
this.atomCount = Containers.createMap();
}

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);
public static AutomaticItpRefToProd2ExplPredPrec create(final Set<VarDecl<?>> explPreferredVars, final ExprSplitter exprSplitter, final MaxAtomCount maxAtomCount) {
checkNotNull(maxAtomCount);
return new AutomaticItpRefToProd2ExplPredPrec(explPreferredVars, exprSplitter, maxAtomCount);
}

@Override
public Prod2Prec<ExplPrec, PredPrec> toPrec(ItpRefutation refutation, int index) {
final Collection<Expr<BoolType>> exprs = exprSplitter.apply(refutation.get(index));
Set<VarDecl<?>> explSelectedVars = new LinkedHashSet<>();
Set<Expr<BoolType>> predSelectedExprs = new LinkedHashSet<>();
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(decl.getType() == Bool()){
explPreferredVars.add(decl);
}
if (explPreferredVars.contains(decl)) {
explSelectedVars.add(decl);
} else allExpl = false;
}
if (!allExpl) predSelectedExprs.add(expr);
}
return Prod2Prec.of(ExplPrec.of(explSelectedVars), PredPrec.of(predSelectedExprs));
final Expr<BoolType> refExpr = refutation.get(index);

final var canonicalAtoms = ExprUtils.getAtoms(refExpr).stream()
.map(ExprUtils::canonize)
.collect(Collectors.toSet());
canonicalAtoms.forEach(
atom -> ExprUtils.getVars(atom).forEach(
decl -> atomCount.computeIfAbsent(decl,(k) -> Containers.createSet()).add(atom)
)
);

explPreferredVars.addAll(
ExprUtils.getVars(refExpr).stream()
.filter(decl -> atomCount.get(decl).size() > maxAtomCount.get(decl) && maxAtomCount.get(decl) != 0 || decl.getType() == Bool())
.collect(Collectors.toSet()));

final var explSelectedVars = ExprUtils.getVars(refExpr).stream()
.filter(explPreferredVars::contains)
.collect(Collectors.toSet());
final var predSelectedExprs = exprSplitter.apply(refExpr).stream()
.filter(expr -> !explPreferredVars.containsAll(ExprUtils.getVars(expr)))
.collect(Collectors.toSet());

return Prod2Prec.of(ExplPrec.of(explSelectedVars), PredPrec.of(predSelectedExprs));
}

@Override
public Prod2Prec<ExplPrec, PredPrec> join(Prod2Prec<ExplPrec, PredPrec> prec1, Prod2Prec<ExplPrec, PredPrec> prec2) {
final ExplPrec joinedExpl = prec1.getPrec1().join(prec2.getPrec1());
final PredPrec joinedPred = prec1.getPrec2().join(prec2.getPrec2());
final var filteredPreds = joinedPred.getPreds().stream()
.filter(pred -> !ExprUtils.getVars(pred).stream().allMatch(decl -> joinedExpl.getVars().contains(decl)))
.filter(pred -> !joinedExpl.getVars().containsAll(ExprUtils.getVars(pred)))
.collect(Collectors.toList());
final PredPrec filteredPred = PredPrec.of(filteredPreds);
return Prod2Prec.of(joinedExpl,filteredPred);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package hu.bme.mit.theta.analysis.prod2.prod2explpred;

import com.google.common.collect.ImmutableSet;
import hu.bme.mit.theta.analysis.expl.ExplPrec;
import hu.bme.mit.theta.analysis.expl.ExplState;
import hu.bme.mit.theta.analysis.pred.PredPrec;
import hu.bme.mit.theta.analysis.pred.PredState;
import hu.bme.mit.theta.analysis.prod2.Prod2Prec;
import hu.bme.mit.theta.analysis.prod2.Prod2State;
import hu.bme.mit.theta.common.container.Containers;
import hu.bme.mit.theta.core.decl.ConstDecl;
import hu.bme.mit.theta.core.decl.Decls;
import hu.bme.mit.theta.core.model.Valuation;
import hu.bme.mit.theta.core.type.Expr;
import hu.bme.mit.theta.core.type.LitExpr;
import hu.bme.mit.theta.core.type.booltype.BoolExprs;
import hu.bme.mit.theta.core.type.booltype.BoolType;
import hu.bme.mit.theta.core.utils.ExprUtils;
import hu.bme.mit.theta.core.utils.PathUtils;
import hu.bme.mit.theta.core.utils.VarIndexing;
import hu.bme.mit.theta.solver.Solver;
import hu.bme.mit.theta.solver.utils.WithPushPop;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.google.common.base.Preconditions.checkNotNull;
import static hu.bme.mit.theta.core.type.booltype.BoolExprs.*;

public class Prod2ExplPredAbstractors {

private Prod2ExplPredAbstractors() {}

public interface Prod2ExplPredAbstractor {

Collection<Prod2State<ExplState, PredState>> createStatesForExpr(final Expr<BoolType> expr, final VarIndexing exprIndexing,
final Prod2Prec<ExplPrec,PredPrec> prec, final VarIndexing precIndexing,
final Function<? super Valuation, ? extends ExplState> valuationToState, final int limit);

}

public static BooleanAbstractor booleanAbstractor(final Solver solver){
return new BooleanAbstractor(solver, false);
}

private static final class BooleanAbstractor implements Prod2ExplPredAbstractor{

private final Solver solver;
private final List<ConstDecl<BoolType>> actLits;
private final String litPrefix;
private static int instanceCounter = 0;
private final boolean split;

public BooleanAbstractor(final Solver solver, final boolean split) {
this.solver = checkNotNull(solver);
this.actLits = new ArrayList<>();
this.litPrefix = "__Prod2ExplPred" + getClass().getSimpleName() + "_" + instanceCounter + "_";
instanceCounter++;
this.split = split;
}

@Override
public Collection<Prod2State<ExplState, PredState>> createStatesForExpr(final Expr<BoolType> expr, final VarIndexing exprIndexing,
final Prod2Prec<ExplPrec, PredPrec> prec, final VarIndexing stateIndexing,
final Function<? super Valuation, ? extends ExplState> valuationToState, final int limit) {
checkNotNull(expr);
checkNotNull(exprIndexing);
checkNotNull(prec);
checkNotNull(stateIndexing);

final List<Expr<BoolType>> preds = new ArrayList<>(prec.getPrec2().getPreds());
generateActivationLiterals(preds.size());

assert actLits.size() >= preds.size();

final List<Prod2State<ExplState,PredState>> states = new LinkedList<>();
try (WithPushPop wp = new WithPushPop(solver)) {
solver.add(PathUtils.unfold(expr, exprIndexing));
for (int i = 0; i < preds.size(); ++i) {
solver.add(Iff(actLits.get(i).getRef(), PathUtils.unfold(preds.get(i), stateIndexing)));
}
while (solver.check().isSat() && (limit == 0 || states.size() < limit)) {
final Valuation model = solver.getModel();

final Valuation valuation = PathUtils.extractValuation(model, stateIndexing);
final ExplState explState = valuationToState.apply(valuation);

final Set<Expr<BoolType>> newStatePreds = Containers.createSet();
final List<Expr<BoolType>> feedback = new LinkedList<>();
feedback.add(True());
for (int i = 0; i < preds.size(); ++i) {
final ConstDecl<BoolType> lit = actLits.get(i);
final Expr<BoolType> pred = preds.get(i);
final Optional<LitExpr<BoolType>> eval = model.eval(lit);
if (eval.isPresent()) {
if (eval.get().equals(True())) {
newStatePreds.add(pred);
feedback.add(lit.getRef());
} else {
newStatePreds.add(prec.getPrec2().negate(pred));
feedback.add(Not(lit.getRef()));
}
}
}
final Set<Expr<BoolType>> simplfiedNewStatePreds = newStatePreds.stream().map(pred -> ExprUtils.simplify(pred,explState)).collect(Collectors.toSet());
final PredState predState = PredState.of(simplfiedNewStatePreds);

final Prod2State<ExplState,PredState> prod2ExplPredState = Prod2State.of(explState,predState);
states.add(prod2ExplPredState);
solver.add(Not(And(PathUtils.unfold(explState.toExpr(), stateIndexing),And(feedback))));
}

}
return states;
}

private void generateActivationLiterals(final int n) {
while (actLits.size() < n) {
actLits.add(Decls.Const(litPrefix + actLits.size(), BoolExprs.Bool()));
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright 2017 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.prod2.prod2explpred;

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

import hu.bme.mit.theta.analysis.Action;
import hu.bme.mit.theta.analysis.Analysis;
import hu.bme.mit.theta.analysis.InitFunc;
import hu.bme.mit.theta.analysis.PartialOrd;
import hu.bme.mit.theta.analysis.TransFunc;
import hu.bme.mit.theta.analysis.expl.ExplPrec;
import hu.bme.mit.theta.analysis.expl.ExplState;
import hu.bme.mit.theta.analysis.expr.ExprAction;
import hu.bme.mit.theta.analysis.pred.PredPrec;
import hu.bme.mit.theta.analysis.pred.PredState;
import hu.bme.mit.theta.analysis.prod2.*;
import hu.bme.mit.theta.analysis.prod2.prod2explpred.Prod2ExplPredAbstractors.Prod2ExplPredAbstractor;
import hu.bme.mit.theta.analysis.prod2.prod2explpred.Prod2ExplPredDedicatedTransFunc;

public final class Prod2ExplPredAnalysis<A extends ExprAction>
implements Analysis<Prod2State<ExplState, PredState>, A, Prod2Prec<ExplPrec, PredPrec>> {

private final PartialOrd<Prod2State<ExplState, PredState>> partialOrd;
private final InitFunc<Prod2State<ExplState, PredState>, Prod2Prec<ExplPrec, PredPrec>> initFunc;
private final TransFunc<Prod2State<ExplState, PredState>, A, Prod2Prec<ExplPrec, PredPrec>> transFunc;

private Prod2ExplPredAnalysis(final Analysis<ExplState, ? super A, ExplPrec> analysis1, final Analysis<PredState, ? super A, PredPrec> analysis2,
final StrengtheningOperator<ExplState, PredState, ExplPrec, PredPrec> strenghteningOperator,
final Prod2ExplPredAbstractor prod2ExplPredAbstractor) {
checkNotNull(analysis1);
checkNotNull(analysis2);
partialOrd = Prod2Ord.create(analysis1.getPartialOrd(), analysis2.getPartialOrd());
initFunc = Prod2InitFunc.create(analysis1.getInitFunc(), analysis2.getInitFunc(), strenghteningOperator);
transFunc = Prod2ExplPredDedicatedTransFunc.create(prod2ExplPredAbstractor);
}

public static <A extends ExprAction> Prod2ExplPredAnalysis<A> create(
final Analysis<ExplState, ? super A, ExplPrec> analysis1, final Analysis<PredState, ? super A, PredPrec> analysis2,
final StrengtheningOperator<ExplState, PredState, ExplPrec, PredPrec> strenghteningOperator,
final Prod2ExplPredAbstractor prod2ExplPredAbstractor) {
return new Prod2ExplPredAnalysis<A>(analysis1, analysis2, strenghteningOperator, prod2ExplPredAbstractor);
}

@Override
public PartialOrd<Prod2State<ExplState, PredState>> getPartialOrd() {
return partialOrd;
}

@Override
public InitFunc<Prod2State<ExplState, PredState>, Prod2Prec<ExplPrec, PredPrec>> getInitFunc() {
return initFunc;
}

@Override
public TransFunc<Prod2State<ExplState, PredState>, A, Prod2Prec<ExplPrec, PredPrec>> getTransFunc() {
return transFunc;
}

}
Loading

0 comments on commit 202f3c0

Please sign in to comment.