package ai.domain.interval;
import ai.domain.DomainException;
import ai.domain.DomainIntf;
/**
* Implementation of interval domain (one-dimension)
*
* @author kjk@mimuw.edu.pl
*
*/
public class Interval implements DomainIntf<Interval> {
public static Interval BOTTOM = new Interval();
public static Interval TOP = new Interval(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
private final IntervalValue value;
private Interval() {
this.value = null;
}
public String toString() {
if (this == BOTTOM)
return "BOT";
return value.toString();
}
public Interval(IntervalValue value) {
assert value != null;
this.value = value;
}
public Interval(double left, double right) {
this.value = new IntervalValue(left, right);
}
public double getLeft() {
if (value == null)
throw new DomainException("Cannot get beginning of BOT interval");
return value.left;
}
public double getRight() {
if (value == null)
throw new DomainException("Cannot get ending of BOT interval");
return value.right;
}
public IntervalValue getValue() {
return value;
}
@Override
public Interval join(Interval other) {
if (isBottom())
return other;
if (other.isBottom())
return this;
if (value.left <= other.value.left && other.value.right <= value.right) { // no
// copy
// if
// not
// required
return this;
} else if (other.value.left <= value.left && value.right <= other.value.right) {
return other;
} else {
IntervalValue val = new IntervalValue(Math.min(value.left, other.value.left), Math.max(value.right,
other.value.right));
return new Interval(val);
}
}
@Override
public Interval meet(Interval other) {
if (value == null || other.value == null)
return BOTTOM;
if (value.right < other.value.left || other.value.right < value.left)
return BOTTOM;
IntervalValue val = new IntervalValue(Math.max(value.left, other.value.left), Math.min(value.right,
other.value.right));
return new Interval(val);
}
@Override
public Interval widen(Interval other) {
if (value == null)
return other;
IntervalValue newValue = new IntervalValue(value.left <= other.value.left ? value.left
: Double.NEGATIVE_INFINITY, other.value.right <= value.right ? value.right : Double.POSITIVE_INFINITY);
return new Interval(newValue);
}
@Override
public boolean leq(Interval other) {
return value == null
|| (other.value != null && other.value.left <= value.left && value.right <= other.value.right);
}
@Override
public boolean isBottom() {
return this == BOTTOM;
}
public boolean equals(Object other) {
if (other instanceof Interval) {
Interval otherInterval = (Interval) other;
if (isBottom())
return otherInterval.isBottom();
else
return !otherInterval.isBottom() && (this.getLeft() == otherInterval.getLeft() && this.getRight() == otherInterval.getRight());
} else
return false;
}
@Override
public boolean equals(Interval other) {
return value.equals(other.value);
}
public Interval add(int i) {
if (isBottom())
return this;
return new Interval(value.add(i));
}
@Override
public Interval getBottom() {
return BOTTOM;
}
@Override
public boolean isTop() {
if (isBottom())
return false;
return value.left == Double.NEGATIVE_INFINITY && value.right == Double.POSITIVE_INFINITY;
}
}