package ai.domain.boxes;
import java.util.ArrayList;
import ai.common.Pair;
import ai.domain.DomainIntf;
import ai.domain.Variable;
import ai.domain.interval.IntervalValue;
import ai.test.comment.domains.DomainConstants;
public class IntegerBoxes implements DomainIntf<IntegerBoxes> {
public static IntegerBoxes BOTTOM = new IntegerBoxes(null, null);
public static class IntegerBoxesException extends RuntimeException {
private static final long serialVersionUID = -5275910399971652215L;
public IntegerBoxesException(String format, Object... args) {
super(String.format(format, args));
}
}
final ArrayList<Variable> variables;
ArrayList<SequencePair> data;
IntegerBoxes(ArrayList<Variable> variables, ArrayList<SequencePair> data) {
if (variables == null && data != null)
throw new IntegerBoxesException("Invalid usage");
if (data == null && variables != null)
throw new IntegerBoxesException("Invalid usage");
this.variables = variables;
this.data = data;
}
public ArrayList<Variable> getVariables() {
return new ArrayList<Variable>(variables);
}
@Override
public boolean isBottom() {
return data == null;
}
@Override
public IntegerBoxes join(IntegerBoxes other) {
if (isBottom())
return other;
if (other.isBottom())
return this;
return IntegerBoxesHelper.applyOpOnCommonVariables(this, other, IntegerBoxesHelper.joinOp);
}
@Override
public IntegerBoxes meet(IntegerBoxes other) {
if (isBottom())
return this;
if (other.isBottom())
return other;
return IntegerBoxesHelper.applyOpOnCommonVariables(this, other, IntegerBoxesHelper.meetOp);
}
@Override
public IntegerBoxes widen(IntegerBoxes other) {
return BoxesWideningOperator.computeWidening(this, other);
}
@Override
public boolean leq(IntegerBoxes other) {
if (isBottom())
return true;
if (other.isBottom())
return false;
Pair<ArrayList<Variable>, Pair<ArrayList<Integer>, ArrayList<Integer>>> x = IntegerBoxesHelper.findVariablesToRemove(this, other);
if (x.right.left.size() > 0) // if we have some variables other does not have!!
return false;
ArrayList<SequencePair> thisData = this.data;
ArrayList<SequencePair> otherData = IntegerBoxesHelper.removeVariables(x.right.right, other.data, other.variables.size());
ArrayList<SequencePair> leqData = IntegerBoxesHelper.leqOp.apply(thisData, otherData, x.left.size());
return leqData == null;
}
@Override
public boolean equals(IntegerBoxes other) {
if (isBottom())
return other.isBottom();
return variables.equals(other.variables) && IntegerBoxesHelper.equals(data, other.data);
}
@Override
public IntegerBoxes getBottom() {
return BOTTOM;
}
private static final String INDENT = " ";
private void processToString(int varId, ArrayList<SequencePair> data, StringBuilder result, String indent) {
if (varId >= variables.size())
return;
result.append("\n");
result.append(indent);
result.append(variables.get(varId).toString());
result.append(":");
double start = Double.NEGATIVE_INFINITY;
ArrayList<SequencePair> lastValue = null;
for (SequencePair elem : data) {
double end = elem.key - 1;
if (lastValue != null) {
result.append(new IntervalValue(start, end));
processToString(varId + 1, lastValue, result, indent + INDENT);
}
result.append("\n" + indent);
start = elem.key;
lastValue = elem.value;
}
if (lastValue != null) {
result.append(new IntervalValue(start, Double.POSITIVE_INFINITY));
processToString(varId + 1, lastValue, result, indent + INDENT);
}
}
public String toString() {
StringBuilder result = new StringBuilder("IntegerBoxes(");
if (variables == null)
result.append(DomainConstants.BOT);
else
processToString(0, data, result, "");
// for(NonRelationalDomain<Interval> x: IntegerBoxesHelper.split(this)){
// result.append(x.toString());
// result.append("\n");
// }
result.append(')');
return result.toString();
}
public boolean equals(Object other) {
if (!(other instanceof IntegerBoxes))
return false;
return equals((IntegerBoxes) other);
}
public static IntegerBoxes getInitialValue() {
return new IntegerBoxes(new ArrayList<Variable>(0), new ArrayList<SequencePair>(0));
}
@Override
public boolean isTop() {
if (isBottom())
return false;
ArrayList<SequencePair> varData = this.data;
final int ZERO_DIM = variables.size();
int i=0;
while (i <= variables.size()) {
if (i == ZERO_DIM)
return varData != null;
if (varData == null || varData.size() !=1)
return false;
SequencePair dataItem = varData.get(0);
if (dataItem.key != Double.NEGATIVE_INFINITY)
return false;
varData = dataItem.value;
i++;
}
return true;
}
public final boolean containsValue(Variable variable) {
return variable != null && variables.contains(variable);
}
}