/* * 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.List; /** * An integer represented using {@link kodkod.engine.bool.BooleanValue boolean values} * and a given {@link kodkod.engine.config.Options.IntEncoding integer encoding}. * * @specfield factory: BooleanFactory * @specfield bits: [0..factory.bitwidth) -> one factory.components * @specfield encoding: factory.intEncoding * @author Emina Torlak */ public abstract class Int { final BooleanFactory factory; /** * Creates an Int with the given factory * @ensures this.factory' = factory */ Int(BooleanFactory factory) { this.factory = factory; } /** * Throws IllegalArgumentException if other.factory != this.factory. * @throws IllegalArgumentException other.factory != this.factory. */ final void validate(Int other) { if (other.factory != factory) throw new IllegalArgumentException("other.factory != this.factory"); } /** * Returns the BooleanValue at the specified index. * @requires 0 <= i < this.factory.bitwidth * @return this.bits[i] */ abstract BooleanValue bit(long i); /** * Returns the little endian two's complement representation of this integer that is * this.factory.bitwidth bits wide. Specifically, the returned list L has * this.factory.bitwidth boolean values such that the meaning of this integer is * 1*[[L.get(0)]] + ... + (1<<i)*[[L.get(i)]] + ... + (-1<<(L.size()-1))*[[L.get(L.size()-1)]]. * @return a list containing the little endian two's complement representation of this integer. * @throws UnsupportedOperationException this integer encoding cannot be converted to two's complement. */ public abstract List<BooleanValue> twosComplementBits(); /** * Returns this.factory * @return this.factory */ public final BooleanFactory factory() { return factory; } /** * Returns the number of bits in the representation of this Int, * including sign bits (if any). * @return this.width */ public abstract int width(); /** * Returns true if all the bits representing this Int * are BooleanConstants. * @return this.bits[int] in BooleanConstant */ public abstract boolean isConstant(); /** * If this Int is constant, returns its value. Otherwise * throws an IllegalStateException. * @return this.isConstant() => [[this.bits]] * @throws IllegalStateException !this.isConstant() */ public abstract int value(); /** * Returns a BooleanValue encoding the comparator circuit * that checks whether the integer represented by this * Int is equal to the integer represented by the specified Int. * @requires this.factory = other.factory * @return BooleanValue encoding the comparator circuit * that checks whether the integer represented by this * Int is equal to the integer represented by the specified Int * @throws IllegalArgumentException this.factory != other.factory */ public abstract BooleanValue eq(Int other); /** * Returns a BooleanValue encoding the comparator circuit * that checks whether the integer represented by this * Int is less than or equal to the integer * represented by the specified Int * @requires this.factory = other.factory * @return BooleanValue encoding the comparator circuit * that checks whether the integer represented by this * Int is less than or equal to the integer * represented by the specified Int * @throws IllegalArgumentException this.factory != other.factory */ public abstract BooleanValue lte(Int other); /** * Returns a BooleanValue encoding the comparator circuit * that checks whether the integer represented by this * Int is less than the integer * represented by the specified Int. * @requires this.factory = other.factory * @return BooleanValue encoding the comparator circuit * that checks whether the integer represented by this * Int is less than the integer * represented by the specified Int * @throws IllegalArgumentException this.factory != other.factory */ public abstract BooleanValue lt(Int other); /** * Returns a BooleanValue encoding the comparator circuit * that checks whether the integer represented by this * Int is greater than or equal to the integer * represented by the specified Int. * @requires this.factory = other.factory * @return BooleanValue encoding the comparator circuit * that checks whether the integer represented by this * Int is greater than or equal to the integer * represented by the specified Int * @throws IllegalArgumentException this.factory != other.factory */ public BooleanValue gte(Int other) { return other.lte(this); } /** * Returns a BooleanValue encoding the comparator circuit * that checks whether the integer represented by this * Int is greater than the integer * represented by the specified Int. * @requires this.factory = other.factory * @return BooleanValue encoding the comparator circuit * that checks whether the integer represented by this * Int is greater than the integer * represented by the specified Int * @throws IllegalArgumentException this.factory != other.factory */ public BooleanValue gt(Int other) { return other.lt(this); } /** * Returns an Int that represents the sum of this and the given Int. * @requires this.factory = other.factory * @return an Int that represents the sum of this and the given Int * @throws IllegalArgumentException this.factory != other.factory */ public abstract Int plus(Int other); /** * Returns an Int that represents the sum of this and the given Ints. * @requires this.factory = others[int].factory * @return an Int that represents the sum of this and the given Ints * @throws IllegalArgumentException this.factory != others[int].factory */ public abstract Int plus(Int... others); /** * Returns an Int that represents the product between this and the given Int. * @requires this.factory = other.factory * @return an Int that represents the product between this and the given Int * @throws UnsupportedOperationException this.encoding does not support multiplication */ public abstract Int multiply(Int other); /** * Returns an Int that represents the product between this and the given Ints. * @requires this.factory = others[int].factory * @return an Int that represents the product between this and the given Ints * @throws UnsupportedOperationException this.encoding does not support multiplication */ public abstract Int multiply(Int... others); /** * Returns an Int that represents the difference between this and the given Int. * @requires this.factory = other.factory * @return an Int that represents the difference between this and the given Int * @throws UnsupportedOperationException this.encoding does not support subtraction */ public abstract Int minus(Int other); /** * Returns an Int that represents the quotient of the division between this and the given Int. * @requires this.factory = other.factory * @return an Int that represents the quotient of the division between this and the given Int * @throws UnsupportedOperationException this.encoding does not support division */ public abstract Int divide(Int other); /** * Returns an Int that represents the remainder of the division between this and the given Int. * @requires this.factory = other.factory * @return an Int that represents the remainder of the division between this and the given Int * @throws UnsupportedOperationException this.encoding does not support division */ public abstract Int modulo(Int other); /** * Returns an Int that evaluates to this if the condition is true, otherwise it * evaluates to the given Int. * @requires other + condition in this.factory.components * @return an Int that evaluates to this if the condition is true, and * to the given Int if the condition is false. */ public abstract Int choice(BooleanValue condition, Int other); /** * Returns an Int that represents the bitwise conjunction of this and the given Int. * @requires this.factory = other.factory * @return an Int that represents the bitwise conjunction of this and the given Int. */ public abstract Int and(Int other); /** * Returns an Int that represents the bitwise conjunction of this and the given Ints. * @requires this.factory = others[int].factory * @return an Int that represents the bitwise conjunction of this and the given Ints. */ public abstract Int and(Int... others); /** * Returns an Int that represents the bitwise disjunction of this and the given Int. * @requires this.factory = other.factory * @return an Int that represents the bitwise disjunction of this and the given Int. */ public abstract Int or(Int other); /** * Returns an Int that represents the bitwise disjunction of this and the given Ints. * @requires this.factory = others[int].factory * @return an Int that represents the bitwise disjunction of this and the given Ints. */ public abstract Int or(Int... others); /** * Returns an Int that represents the bitwise XOR of this and the given Int. * @requires this.factory = other.factory * @return an Int that represents the bitwise XOR of this and the given Int. * @throws UnsupportedOperationException this.encoding does not support XOR */ public abstract Int xor(Int other); /** * Returns an Int that represents this shifted to the left by the given Int. * @requires this.factory = other.factory * @return an Int that represents this shifted to the left by the given Int. * @throws UnsupportedOperationException this.encoding does not support SHL */ public abstract Int shl(Int other); /** * Returns an Int that represents this shifted to the right by the given Int, * with zero extension. * @requires this.factory = other.factory * @return an Int that represents this shifted to the right by the given Int, * with zero extension. * @throws UnsupportedOperationException this.encoding does not support SHR */ public abstract Int shr(Int other); /** * Returns an Int that represents this shifted to the right by the given Int, * with sign extension. * @requires this.factory = other.factory * @return an Int that represents this shifted to the right by the given Int, * with sign extension. * @throws UnsupportedOperationException this.encoding does not support SHA */ public abstract Int sha(Int other); /** * Returns an Int that represents the negation of this integer. * @return -[[this]] * @throws UnsupportedOperationException this.encoding does not support negation */ public abstract Int negate(); /** * Returns an Int that represents bitwise negation of this integer. * @return ~[[this]] * @throws UnsupportedOperationException this.encoding does not support bitwise negation */ public abstract Int not(); /** * Returns an Int that represents the absolute value of this integer. * @return abs([[this]]) */ public abstract Int abs(); /** * Returns an Int that represents the signum of this integer. * @return sgn([[this]]) */ public abstract Int sgn(); }