package ai.domain.generic;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import ai.common.Pair;
import ai.domain.DomainException;
import ai.domain.DomainIntf;
import ai.test.comment.domains.DomainConstants;
public class ProductDomain<D1 extends DomainIntf<D1>, D2 extends DomainIntf<D2>> implements DomainIntf<ProductDomain<D1, D2>> {
private final Pair<D1,D2> values;
private ProductDomain() {
this.values = null;
}
public D1 getLeft() {
if (values == null)
throw new DomainException("Invalid usage");
return values.left;
}
public D2 getRight() {
if (values == null)
throw new DomainException("Invalid usage");
return values.right;
}
public ProductDomain(Pair<D1,D2> values) {
if (values == null || values.left.isBottom() || values.right.isBottom())
throw new DomainException("Invalid usage");
this.values = values;
}
@Override
public boolean isBottom() {
return values == null;
}
@Override
public ProductDomain<D1, D2> join(ProductDomain<D1, D2> other) {
if (isBottom())
return other;
if (other.isBottom())
return this;
return new ProductDomain<D1, D2>(new Pair<D1, D2>(values.left.join(other.values.left),
values.right.join(other.values.right)));
}
@Override
public ProductDomain<D1, D2> meet(ProductDomain<D1, D2> other) {
if (isBottom())
return other;
if (other.isBottom())
return this;
D1 left = values.left.meet(other.values.left);
if (left.isBottom())
return new ProductDomain<D1, D2>();
D2 right = values.right.meet(other.values.right);
if (right.isBottom())
return new ProductDomain<D1, D2>();
return new ProductDomain<D1, D2>(new Pair<D1,D2>(left, right));
}
@Override
public ProductDomain<D1, D2> widen(ProductDomain<D1, D2> other) {
if (isBottom())
return other;
if (other.isBottom())
return this;
return new ProductDomain<D1, D2>(new Pair<D1, D2>(values.left.widen(other.values.left),
values.right.widen(other.values.right)));
}
@Override
public boolean leq(ProductDomain<D1, D2> other) {
if (isBottom())
return true;
if (other.isBottom())
return false;
return values.left.leq(other.values.left) && values.right.leq(other.values.right);
}
@Override
public boolean equals(ProductDomain<D1, D2> other) {
if (isBottom())
return other.isBottom();
if (other.isBottom())
return false;
return values.equals(other.values);
}
public String toString(){
String value = isBottom() ? DomainConstants.BOT : values.left.toString()+" X "+values.right.toString();
return "ProductDomain("+value+")";
}
public ProductDomain<D1, D2> setRight(D2 value) {
if (value.isBottom())
return new ProductDomain<D1, D2>();
return new ProductDomain<D1, D2>(values.setRight(value));
}
public ProductDomain<D1, D2> setLeft(D1 value) {
if (value.isBottom())
return new ProductDomain<D1, D2>();
return new ProductDomain<D1, D2>(values.setLeft(value));
}
@Override
public ProductDomain<D1, D2> getBottom() {
return new ProductDomain<D1, D2>();
}
public static <D1 extends DomainIntf<D1>, D2 extends DomainIntf<D2>> ProductDomain<D1, D2> create(D1 left, D2 right) {
return new ProductDomain<D1, D2>(Pair.create(left, right));
}
public static <D1 extends DomainIntf<D1>, D2 extends DomainIntf<D2>> ProductDomain<D1, D2> getStaticBottom(){
return new ProductDomain<D1, D2>();
}
@Override
public boolean isTop() {
if (isBottom())
return false;
return values.left.isTop() && values.right.isTop();
}
}