package janala.interpreters;
import java.util.Map;
public final class SymbolicIntCompareConstraint extends Constraint {
public final SymOrInt left;
public final SymOrInt right;
public final COMPARISON_OPS op;
@Override
public boolean equals(Object o) {
if (o == null) {
return false;
} else if (o == this) {
return true;
} else if (o instanceof SymbolicIntCompareConstraint) {
SymbolicIntCompareConstraint other = (SymbolicIntCompareConstraint) o;
return left.equals(other.left) && right.equals(other.right) &&
(op == other.op);
} else {
return false;
}
}
public SymbolicIntCompareConstraint(SymOrInt left, SymOrInt right, COMPARISON_OPS op) {
this.left = left;
this.right = right;
this.op = op;
}
public SymbolicIntCompareConstraint(SymbolicIntCompareConstraint from) {
this.left = from.left;
this.right = from.right;
this.op = from.op;
}
@Override
public void accept(ConstraintVisitor v) {
v.visitSymbolicIntCompare(this);
}
@Override
public Constraint not() {
COMPARISON_OPS retOp = op;
if (op == COMPARISON_OPS.EQ) {
retOp = COMPARISON_OPS.NE;
} else if (op == COMPARISON_OPS.NE) {
retOp = COMPARISON_OPS.EQ;
} else if (op == COMPARISON_OPS.GT) {
retOp = COMPARISON_OPS.LE;
} else if (op == COMPARISON_OPS.GE) {
retOp = COMPARISON_OPS.LT;
} else if (op == COMPARISON_OPS.LT) {
retOp = COMPARISON_OPS.GE;
} else if (op == COMPARISON_OPS.LE) {
retOp = COMPARISON_OPS.GT;
}
return new SymbolicIntCompareConstraint(left, right, retOp);
}
public Constraint substitute(Map<String, Long> assignments) {
long val;
SymOrInt tmp1, tmp2;
Constraint ret2 = null;
if (left.isSym && assignments.containsKey(left.getSym())) {
tmp1 = new SymOrInt(assignments.get(left.getSym()));
} else {
tmp1 = left;
}
if (right.isSym && assignments.containsKey(right.getSym())) {
tmp2 = new SymOrInt(assignments.get(right.getSym()));
} else {
tmp2 = right;
}
if (!tmp1.isSym && !tmp2.isSym) {
val = tmp1.getConstant() - tmp2.getConstant();
} else {
return new SymbolicIntCompareConstraint(tmp1, tmp2, this.op);
}
if (this.op == COMPARISON_OPS.EQ) {
ret2 = (val == 0) ? SymbolicTrueConstraint.instance : SymbolicFalseConstraint.instance;
} else if (this.op == COMPARISON_OPS.NE) {
ret2 = (val != 0) ? SymbolicTrueConstraint.instance : SymbolicFalseConstraint.instance;
} else if (this.op == COMPARISON_OPS.LE) {
ret2 = (val <= 0) ? SymbolicTrueConstraint.instance : SymbolicFalseConstraint.instance;
} else if (this.op == COMPARISON_OPS.LT) {
ret2 = (val < 0) ? SymbolicTrueConstraint.instance : SymbolicFalseConstraint.instance;
} else if (this.op == COMPARISON_OPS.GE) {
ret2 = (val >= 0) ? SymbolicTrueConstraint.instance : SymbolicFalseConstraint.instance;
} else if (this.op == COMPARISON_OPS.GT) {
ret2 = (val > 0) ? SymbolicTrueConstraint.instance : SymbolicFalseConstraint.instance;
}
return ret2;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(left);
sb.append('-');
sb.append(right);
if (op == COMPARISON_OPS.EQ) {
sb.append("==");
sb.append('0');
} else if (op == COMPARISON_OPS.NE) {
sb.append("!=");
sb.append('0');
} else if (op == COMPARISON_OPS.LE) {
sb.append("<=");
sb.append('0');
} else if (op == COMPARISON_OPS.LT) {
sb.append("<");
sb.append('0');
} else if (op == COMPARISON_OPS.GE) {
sb.append(">=");
sb.append('0');
} else if (op == COMPARISON_OPS.GT) {
sb.append(">");
sb.append('0');
}
return sb.toString();
}
}