/* * Kodkod -- Copyright (c) 2005-present, Emina Torlak * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package kodkod.engine.bool; import java.util.Iterator; /** * ExprOperator associated with a {@link kodkod.engine.bool.BooleanValue boolean value}. * * @specfield ordinal: [0..5] * @invariant AND.ordinal = 0 && OR.ordinal = 1 && ITE.ordinal = 2 && * NOT.ordinal = 2 && VAR.ordinal = 4 && CONST.ordinal = 5 * @author Emina Torlak */ public abstract class Operator implements Comparable<Operator>{ final int ordinal; private Operator(int ordinal) { this.ordinal = ordinal; } /** * Returns the ordinal of this operator constant. * @return the ordinal of this operator constant. */ public final int ordinal() { return ordinal; } /** * Returns an integer i such that i < 0 if this.ordinal < op.ordinal, * i = 0 when this.ordinal = op.ordinal, and i > 0 when this.ordinal > op.ordinal. * @return i: int | this.ordinal < op.ordinal => i < 0, * this.ordinal = op.ordinal => i = 0, i > 0 * @throws NullPointerException op = null */ public int compareTo(Operator op) { return ordinal() - op.ordinal(); } /** * N-ary {@link MultiGate AND} operator. */ public static final Nary AND = new Nary(0) { public String toString() { return "&"; } /** @return true */ public BooleanConstant identity() { return BooleanConstant.TRUE; } /** @return false */ public BooleanConstant shortCircuit() { return BooleanConstant.FALSE; } /** @return OR */ public Nary complement() { return OR; } }; /** * N-ary {@link MultiGate OR} operator. */ public static final Nary OR = new Nary(1) { public String toString() { return "|"; } /** @return false */ public BooleanConstant identity() { return BooleanConstant.FALSE; } /** @return true */ public BooleanConstant shortCircuit() { return BooleanConstant.TRUE; } /** @return AND */ public Nary complement() { return AND; } }; /** * Ternary {@link ITEGate if-then-else} operator. */ public static final Ternary ITE = new Ternary(2) { public String toString() { return "?"; } }; /** * Unary {@link NotGate negation} operator. */ public static final Operator NOT = new Operator(3) { public String toString() { return "!"; } }; /** * Zero-arity {@link BooleanVariable variable} operator. */ public static final Operator VAR = new Operator(4) { public String toString() { return "var"; } }; /** * Zero-arity {@link BooleanConstant constant} operator. */ public static final Operator CONST = new Operator(5) { public String toString() { return "const"; } }; /** * An n-ary operator, where n>=2 */ public static abstract class Nary extends Operator { private Nary(int ordinal) { super(ordinal); } /** * Returns the hashcode for a gate v such that * v.op = this && v.inputs[int] = f0 + f1 * @return f0.hash(this) + f1.hash(this) */ int hash(BooleanFormula f0, BooleanFormula f1) { return f0.hash(this) + f1.hash(this); } /** * Returns the hashcode for a gate v such that * v.op = this && v.iterator() = formulas. * @return sum(formulas.hash(this)) */ int hash(Iterator<BooleanFormula> formulas) { int sum = 0; while(formulas.hasNext()) sum += formulas.next().hash(this); return sum; } /** * Returns the boolean constant <i>c</i> such that * for all logical values <i>x</i>, <i>c</i> composed * with <i>x</i> using this operator will result in <i>x</i>. * @return the identity value of this binary operator */ public abstract BooleanConstant identity(); /** * Returns the boolean constant <i>c</i> such that * for all logical values <i>x</i>, <i>c</i> composed * with <i>x</i> using this operator will result in <i>c</i>. * @return the short circuiting value of this binary operator */ public abstract BooleanConstant shortCircuit(); /** * Returns the binary operator whose identity and short circuit * values are the negation of this operator's identity and * short circuit. * @return the complement of this binary operator */ public abstract Operator.Nary complement(); } static abstract class Ternary extends Operator { private Ternary(int ordinal) { super(ordinal); } /** * Returns the hashcode for a gate v such that * v = (i ? t : e) * @return 3*i.hash(this) + 5*t.hash(this) + 7*e.hash(this) */ int hash(BooleanFormula i, BooleanFormula t, BooleanFormula e) { return 3*i.hash(this) + 5*t.hash(this) + 7*e.hash(this); } } }