001package org.clafer.ir;
002
003import org.clafer.common.Check;
004
005/**
006 *
007 * @author jimmy
008 */
009public class IrSetTest extends IrAbstractBool implements IrBoolExpr {
010
011    private final IrSetExpr left;
012    private final Op op;
013    private final IrSetExpr right;
014
015    IrSetTest(IrSetExpr left, Op op, IrSetExpr right, IrBoolDomain domain) {
016        super(domain);
017        this.left = Check.notNull(left);
018        this.op = Check.notNull(op);
019        this.right = Check.notNull(right);
020    }
021
022    public IrSetExpr getLeft() {
023        return left;
024    }
025
026    public Op getOp() {
027        return op;
028    }
029
030    public IrSetExpr getRight() {
031        return right;
032    }
033
034    @Override
035    public IrBoolExpr negate() {
036        return new IrSetTest(left, op.negate(), right, getDomain().invert());
037    }
038
039    @Override
040    public boolean isNegative() {
041        return false;
042    }
043
044    @Override
045    public <A, B> B accept(IrBoolExprVisitor<A, B> visitor, A a) {
046        return visitor.visit(this, a);
047    }
048
049    @Override
050    public <A, B> B accept(IrIntExprVisitor<A, B> visitor, A a) {
051        return visitor.visit(this, a);
052    }
053
054    @Override
055    public boolean equals(Object obj) {
056        if (obj instanceof IrSetTest) {
057            IrSetTest other = (IrSetTest) obj;
058            return left.equals(other.left) && op.equals(other.op) && right.equals(other.right) && super.equals(other);
059        }
060        return false;
061    }
062
063    @Override
064    public int hashCode() {
065        // op.hashCode() can change between runs which makes the output change
066        // every time.
067        return left.hashCode() ^ op.ordinal() ^ right.hashCode();
068    }
069
070    @Override
071    public String toString() {
072        return left + " " + op.getSyntax() + " " + right;
073    }
074
075    public static enum Op {
076
077        Equal("="),
078        NotEqual("!=");
079        private final String syntax;
080
081        Op(String syntax) {
082            this.syntax = syntax;
083        }
084
085        public String getSyntax() {
086            return syntax;
087        }
088
089        public Op negate() {
090            switch (this) {
091                case Equal:
092                    return NotEqual;
093                case NotEqual:
094                    return Equal;
095                default:
096                    throw new IllegalStateException();
097            }
098        }
099    }
100}