
it.unive.lisa.analysis.numeric.Parity Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of lisa-analyses Show documentation
Show all versions of lisa-analyses Show documentation
A library for static analysis
The newest version!
package it.unive.lisa.analysis.numeric;
import it.unive.lisa.analysis.BaseLattice;
import it.unive.lisa.analysis.Lattice;
import it.unive.lisa.analysis.SemanticException;
import it.unive.lisa.analysis.SemanticOracle;
import it.unive.lisa.analysis.nonrelational.value.BaseNonRelationalValueDomain;
import it.unive.lisa.analysis.nonrelational.value.ValueEnvironment;
import it.unive.lisa.program.cfg.ProgramPoint;
import it.unive.lisa.symbolic.value.Constant;
import it.unive.lisa.symbolic.value.Identifier;
import it.unive.lisa.symbolic.value.ValueExpression;
import it.unive.lisa.symbolic.value.operator.AdditionOperator;
import it.unive.lisa.symbolic.value.operator.DivisionOperator;
import it.unive.lisa.symbolic.value.operator.ModuloOperator;
import it.unive.lisa.symbolic.value.operator.MultiplicationOperator;
import it.unive.lisa.symbolic.value.operator.RemainderOperator;
import it.unive.lisa.symbolic.value.operator.SubtractionOperator;
import it.unive.lisa.symbolic.value.operator.binary.BinaryOperator;
import it.unive.lisa.symbolic.value.operator.binary.ComparisonEq;
import it.unive.lisa.symbolic.value.operator.unary.NumericNegation;
import it.unive.lisa.symbolic.value.operator.unary.UnaryOperator;
import it.unive.lisa.util.representation.StringRepresentation;
import it.unive.lisa.util.representation.StructuredRepresentation;
/**
* The overflow-insensitive Parity abstract domain, tracking if a numeric value
* is even or odd, implemented as a {@link BaseNonRelationalValueDomain},
* handling top and bottom values for the expression evaluation and bottom
* values for the expression satisfiability. Top and bottom cases for least
* upper bound, widening and less or equals operations are handled by
* {@link BaseLattice} in {@link BaseLattice#lub}, {@link BaseLattice#widening}
* and {@link BaseLattice#lessOrEqual} methods, respectively.
*
* @author Vincenzo Arceri
*/
public class Parity implements BaseNonRelationalValueDomain {
/**
* The abstract even element.
*/
public static final Parity EVEN = new Parity((byte) 3);
/**
* The abstract odd element.
*/
public static final Parity ODD = new Parity((byte) 2);
/**
* The abstract top element.
*/
public static final Parity TOP = new Parity((byte) 0);
/**
* The abstract bottom element.
*/
public static final Parity BOTTOM = new Parity((byte) 1);
private final byte parity;
/**
* Builds the parity abstract domain, representing the top of the parity
* abstract domain.
*/
public Parity() {
this((byte) 0);
}
/**
* Builds the parity instance for the given parity value.
*
* @param parity the sign (0 = top, 1 = bottom, 2 = odd, 3 = even)
*/
public Parity(
byte parity) {
this.parity = parity;
}
@Override
public Parity top() {
return TOP;
}
@Override
public Parity bottom() {
return BOTTOM;
}
@Override
public StructuredRepresentation representation() {
if (isBottom())
return Lattice.bottomRepresentation();
if (isTop())
return Lattice.topRepresentation();
String repr;
if (this == EVEN)
repr = "Even";
else
repr = "Odd";
return new StringRepresentation(repr);
}
@Override
public Parity evalNullConstant(
ProgramPoint pp,
SemanticOracle oracle) {
return top();
}
@Override
public Parity evalNonNullConstant(
Constant constant,
ProgramPoint pp,
SemanticOracle oracle) {
if (constant.getValue() instanceof Integer) {
Integer i = (Integer) constant.getValue();
return i % 2 == 0 ? EVEN : ODD;
}
return top();
}
/**
* Yields whether or not this is the even parity.
*
* @return {@code true} if that condition holds
*/
public boolean isEven() {
return this == EVEN;
}
/**
* Yields whether or not this is the odd parity.
*
* @return {@code true} if that condition holds
*/
public boolean isOdd() {
return this == ODD;
}
@Override
public Parity evalUnaryExpression(
UnaryOperator operator,
Parity arg,
ProgramPoint pp,
SemanticOracle oracle) {
if (operator == NumericNegation.INSTANCE)
return arg;
return top();
}
@Override
public Parity evalBinaryExpression(
BinaryOperator operator,
Parity left,
Parity right,
ProgramPoint pp,
SemanticOracle oracle) {
if (left.isTop() || right.isTop())
return top();
if (operator instanceof AdditionOperator || operator instanceof SubtractionOperator)
if (right.equals(left))
return EVEN;
else
return ODD;
else if (operator instanceof MultiplicationOperator)
if (left.isEven() || right.isEven())
return EVEN;
else
return ODD;
else if (operator instanceof DivisionOperator)
if (left.isOdd())
return right.isOdd() ? ODD : EVEN;
else
return right.isOdd() ? EVEN : TOP;
else if (operator instanceof ModuloOperator || operator instanceof RemainderOperator)
return TOP;
return TOP;
}
@Override
public Parity lubAux(
Parity other)
throws SemanticException {
return TOP;
}
@Override
public boolean lessOrEqualAux(
Parity other)
throws SemanticException {
return false;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + parity;
return result;
}
@Override
public boolean equals(
Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Parity other = (Parity) obj;
if (parity != other.parity)
return false;
return true;
}
@Override
public ValueEnvironment assumeBinaryExpression(
ValueEnvironment environment,
BinaryOperator operator,
ValueExpression left,
ValueExpression right,
ProgramPoint src,
ProgramPoint dest,
SemanticOracle oracle)
throws SemanticException {
if (operator == ComparisonEq.INSTANCE)
if (left instanceof Identifier) {
Parity eval = eval(right, environment, src, oracle);
if (eval.isBottom())
return environment.bottom();
return environment.putState((Identifier) left, eval);
} else if (right instanceof Identifier) {
Parity eval = eval(left, environment, src, oracle);
if (eval.isBottom())
return environment.bottom();
return environment.putState((Identifier) right, eval);
}
return environment;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy