001package org.clafer.ast;
002
003import java.util.Arrays;
004import org.clafer.common.Check;
005import org.clafer.common.Util;
006
007/**
008 * foldl1 op operands. Note that even implies is left-associative.
009 *
010 * @author jimmy
011 */
012public class AstBoolArithm implements AstBoolExpr {
013
014    private final Op op;
015    private final AstBoolExpr[] operands;
016
017    AstBoolArithm(Op op, AstBoolExpr[] operands) {
018        this.op = Check.notNull(op);
019        this.operands = Check.noNullsNotEmpty(operands);
020    }
021
022    public Op getOp() {
023        return op;
024    }
025
026    public AstBoolExpr[] getOperands() {
027        return operands;
028    }
029
030    @Override
031    public <A, B> B accept(AstExprVisitor<A, B> visitor, A a) {
032        return visitor.visit(this, a);
033    }
034
035    @Override
036    public boolean equals(Object obj) {
037        if (obj instanceof AstBoolArithm) {
038            AstBoolArithm other = (AstBoolArithm) obj;
039            return op.equals(other.op) && Arrays.equals(operands, other.operands);
040        }
041        return false;
042    }
043
044    @Override
045    public int hashCode() {
046        // op.hashCode() can change between runs which makes the output change
047        // every time.
048        return op.ordinal() ^ Arrays.hashCode(operands);
049    }
050
051    @Override
052    public String toString() {
053        return "(" + Util.intercalate(") " + op.getSyntax() + " (", operands) + ")";
054    }
055
056    public static enum Op {
057
058        And("&&"),
059        IfOnlyIf("<=>"),
060        Implies("=>"),
061        Or("||"),
062        Xor("xor");
063        private final String syntax;
064
065        private Op(String syntax) {
066            this.syntax = syntax;
067        }
068
069        public String getSyntax() {
070            return syntax;
071        }
072    }
073}