package sv_esc;
/* Solution:
*/
// NOTE: no specification yet that the elements of the Bag.contents array are
// what they are supposed tdo be (e.g. only slightly changed by add, remove,
// properly initalized by initializers).
/*@ code_java_math */
class Bag {
int[] contents; //@ invariant contents != null;
int n;
//@ invariant 0 <= n;
//@ invariant n <= contents.length;
//@ requires input != null;
// default assignable includes this.n and this.contents and this.contents[*]
Bag(int[] input) {
n = input.length;
contents = new int[n];
arraycopy(input, 0, contents, 0, n);
}
//@ requires b != null;
Bag(Bag b) {
contents = new int[0]; // error in code corrected
n = 0; // added by DRC, so that invariants hold before a method call
this.add(b);
}
void removeOnce(int elt) {
//@ loop_invariant 0 <= i && i <= n && n >= 0 && n <= contents.length; // added by DRC
for (int i = 0; i < n; i++) { // error in code corrected
if (contents[i] == elt ) {
n--;
contents[i] = contents[n];
return;
}
}
}
void removeAll(int elt) {
//@ loop_invariant i>=0 && i<=n && n >= 0 && n <= contents.length; // DRC modified
for (int i = 0; i < n; i++) { // error in code corrected
if (contents[i] == elt ) {
n--;
contents[i] = contents[n];
i--; // DRC modified
}
}
}
//@ ensures \result >= 0;
/*@ pure @*/ int getCount(int elt) {
int count = 0;
//@ loop_invariant i>=0 && i<=n;
//@ loop_invariant count >= 0;
for (int i = 0; i < n; i++)
if (contents[i] == elt) count++;
return count;
}
//@ modifies n, contents, contents[*]; // added by DRC
void add(int elt) {
if (n == contents.length) {
int[] new_contents = new int[2*n+1]; // error in code corrected
arraycopy(contents, 0, new_contents, 0, n);
contents = new_contents;
}
contents[n]=elt;
n++;
}
//@ requires b != null;
//@ modifies n,contents; // DRC added
void add(Bag b) {
int[] new_contents = new int[n+b.n];
arraycopy(this.contents, 0, new_contents, 0, n);
arraycopy(b.contents, 0, new_contents, n, b.n);
contents = new_contents;
n = n + b.n; // DRC added
}
//@ requires src != null;
//@ requires srcOff >=0;
//@ requires dest != null;
//@ requires destOff >=0;
//@ requires length >=0;
//@ requires srcOff + length <= src.length;
//@ requires destOff + length <= dest.length;
//@ assignable dest[*];
private static void arraycopy(int[] src,
int srcOff,
int[] dest,
int destOff,
int length) {
/*@ loop_invariant i>=0 && i<=length; @*/
for( int i=0 ; i<length; i++) {
dest[destOff+i] = src[srcOff+i];
}
}
}