hu.bme.mit.theta.xta.analysis.zone.lu.LuZoneState Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of theta-xta-analysis Show documentation
Show all versions of theta-xta-analysis Show documentation
Xta Analysis subproject in the Theta model checking framework
The newest version!
/*
* 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.xta.analysis.zone.lu;
import com.google.common.collect.Lists;
import hu.bme.mit.theta.analysis.expr.ExprState;
import hu.bme.mit.theta.analysis.zone.BoundFunc;
import hu.bme.mit.theta.analysis.zone.ZoneState;
import hu.bme.mit.theta.common.container.Containers;
import hu.bme.mit.theta.core.decl.ParamDecl;
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.type.rattype.RatType;
import hu.bme.mit.theta.core.utils.ExprUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.StringJoiner;
import static com.google.common.base.Preconditions.checkNotNull;
import static hu.bme.mit.theta.core.type.booltype.BoolExprs.And;
import static hu.bme.mit.theta.core.type.booltype.BoolExprs.Exists;
import static hu.bme.mit.theta.core.type.booltype.BoolExprs.Imply;
import static hu.bme.mit.theta.core.type.booltype.BoolExprs.True;
import static hu.bme.mit.theta.core.type.rattype.RatExprs.Gt;
import static hu.bme.mit.theta.core.type.rattype.RatExprs.Lt;
import static hu.bme.mit.theta.core.type.rattype.RatExprs.Rat;
public final class LuZoneState implements ExprState {
private static final int HASH_SEED = 5261;
private final ZoneState zone;
private final BoundFunc boundFunc;
private volatile int hashCode = 0;
private volatile Expr expr = null;
private LuZoneState(final ZoneState zone, final BoundFunc boundFunc) {
this.zone = checkNotNull(zone);
this.boundFunc = checkNotNull(boundFunc);
}
public static LuZoneState of(final ZoneState zone, final BoundFunc boundFunc) {
return new LuZoneState(zone, boundFunc);
}
public ZoneState getZone() {
return zone;
}
public BoundFunc getBoundFunc() {
return boundFunc;
}
public LuZoneState withBoundFunc(final BoundFunc boundFunc) {
return LuZoneState.of(zone, boundFunc);
}
@Override
public boolean isBottom() {
return zone.isBottom();
}
public boolean isLeq(final LuZoneState that) {
return that.boundFunc.isLeq(this.boundFunc) && this.zone.isLeq(that.zone, that.boundFunc);
}
@Override
public Expr toExpr() {
Expr result = expr;
if (result == null) {
// TODO create class for mapping
final Map, ParamDecl>> mapping = Containers.createMap();
final Expr zoneExpr = ExprUtils.close(zone.toExpr(), mapping);
final Collection> conjuncts = new ArrayList<>();
conjuncts.addAll(ExprUtils.getConjuncts(zoneExpr));
final Collection> vars = mapping.keySet();
for (final VarDecl> vx : vars) {
@SuppressWarnings("unchecked") final VarDecl dx = (VarDecl) vx;
@SuppressWarnings("unchecked") final ParamDecl dxp = (ParamDecl) mapping.get(
dx);
final Expr x = dx.getRef();
final Expr xp = dxp.getRef();
final Optional optLower = boundFunc.getLower(dx);
if (optLower.isPresent()) {
final int lower = optLower.get();
final Expr lx = Rat(lower, 1);
// x > xp imply xp > L(x)
final Expr lowerExpr = Imply(Gt(x, xp), Gt(xp, lx));
conjuncts.add(lowerExpr);
}
final Optional optUpper = boundFunc.getUpper(dx);
if (optUpper.isPresent()) {
final int upper = optUpper.get();
final Expr ux = Rat(upper, 1);
// x < xp imply x > U(x)
final Expr upperExpr = Imply(Lt(x, xp), Gt(x, ux));
conjuncts.add(upperExpr);
}
}
if (conjuncts.isEmpty()) {
result = True();
} else {
result = Exists(Lists.newArrayList(mapping.values()), And(conjuncts));
}
expr = result;
}
return result;
}
@Override
public int hashCode() {
int result = hashCode;
if (result == 0) {
result = HASH_SEED;
result = 31 * result + zone.hashCode();
result = 31 * result + boundFunc.hashCode();
hashCode = result;
}
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
} else if (obj != null && this.getClass() == obj.getClass()) {
final LuZoneState that = (LuZoneState) obj;
return this.zone.equals(that.zone) && this.boundFunc.equals(that.boundFunc);
} else {
return false;
}
}
@Override
public String toString() {
final StringJoiner sj = new StringJoiner("\n");
sj.add(zone.toString());
if (!boundFunc.getLowerVars().isEmpty()) {
sj.add("L:");
boundFunc.getLowerVars()
.forEach(c -> sj.add(c.getName() + " <- " + boundFunc.getLower(c).get()));
}
if (!boundFunc.getUpperVars().isEmpty()) {
sj.add("U:");
boundFunc.getUpperVars()
.forEach(c -> sj.add(c.getName() + " <- " + boundFunc.getUpper(c).get()));
}
return sj.toString();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy