public class Interval implements IntSet { /*@ spec_public @*/ protected int lb, ub; //@ in state; /*@ spec_public @*/ protected boolean inclusive = false; //@ in state; //@ public invariant lb <= ub; //@ public invariant ub == Integer.MAX_VALUE <==> inclusive; //@ requires l <= u; //@ assignable state; //@ ensures lb == l && ub == u; public Interval(int l, int u) { lb = l; ub = u; } //@ ensures \result == lb; public /*@ pure @*/ int lower() { return lb; } //@ ensures \result == ub; public /*@ pure @*/ int upper() { return ub; } //@ also //@ ensures \result <==> (lb <= i && i < ub) || (inclusive && i == ub); public /*@ pure @*/ boolean contains(int i) { return lb <= i && i < ub || (inclusive && i == ub); } public int choose() { return lb; } public void add(int i) { if (!contains(i)) { //@ assert (i < lb || i >= ub) && (!inclusive || i != ub); if (i < lb) { lb = i; } else { //@ assert i >= ub && (!inclusive || i != ub); if (i < Integer.MAX_VALUE) { ub = i+1; } else { ub = i; inclusive = true; } } //@ contains(i); } } public void remove(int i) { if (!contains(i)) { return; } //@ assert lb <= i && i < ub || (inclusive && i == ub); if (lb <= i && i < ub) { if (i-lb > ub-i) { lb = i+1; } else { ub = i-1; } } else if (inclusive) //@ assert i == ub && ub == Integer.MAX_VALUE; lb = i-1; ub = i-1; inclusive = false; } //@ !contains(i); } public /*@ pure @*/ int size() { return ub - lb - 1; } }