/* ESC/Java2 Exercise: This class implements a Bag of integers, using an array. Add JML specs to this class, to stop ESC/Java2 from complaining. However, beware that there are also errors in the code that you may have to fix to stop ESC/Java2 from complaining. (More generally, feel free to improve the code to make it easier to specify in JML, but _only_ do this if you think this makes the code better/easier to understand. The only JML keywords needed for this are requires invariant ensures If you want, you can also use non_null as abbreviation. While developing your specs, it may be useful to use the keywords assert to add additional assertions in source code, to find out what ESC/Java2 can - or cannot - prove at a given program point. */ public class Bag { int[] contents; //@ invariant contents != null; int n; //@ invariant n <= contents.length && n >= 0; //@ requires input != null; //@ requires input.length >= 0; //@ ensures contents.length == input.length; //@ ensures n == contents.length; // post: contenido de contents == contenido de input Bag(int[] input) { n = input.length; contents = new int[n]; arraycopy(input, 0, contents, 0, n); } Bag() { n =0; contents = new int[0]; } //@ requires n > 0; // post: el ene ke sale es igual al ene ke entro menos 1 void removeOnce(int elt) { for (int i = 0; i < n; i++) { if (contents[i] == elt ) { n--; contents[i] = contents[n]; int[] tmp = new int[n]; arraycopy(contents, 0, tmp, 0, n); contents = tmp; return; } } } //@ requires n > 0; void removeAll(int elt) { for (int i = 0; i < n; i++) { if (contents[i] == elt) { n--; contents[i] = contents[n]; } } int[] tmp = new int[n]; arraycopy(contents, 0, tmp, 0, n); contents = tmp; } int getCount(int elt) { int count = 0; for (int i = 0; i < n; i++) if (contents[i] == elt) count++; return count; } /* Warning: you may have a hard time checking the method "add" below. ESC/Java2 may warn about a very subtle bug that can be hard to spot. If you cannot find the problem after staring at the code for an hour, feel free to stop. */ void add(int elt) { if (n == contents.length) { int[] new_contents = new int[n > 0 ? 2*n : 1]; arraycopy(contents, 0, new_contents, 0, n); contents = new_contents; } contents[n]=elt; n++; } //@ requires b != null && b.contents != null; void add(Bag b) { int[] new_contents = new int[n + b.n]; arraycopy(contents, 0, new_contents, 0, n); arraycopy(b.contents, 0, new_contents, n, b.n); contents = new_contents; } //@ requires a != null; void add(int[] a) { this.add(new Bag(a)); } //@ requires b != null && b.contents != null; Bag(Bag b) { contents = new int[b.n]; this.add(b); } //@ requires src != null; //@ requires dest != null; //@ requires srcOff >= 0 && srcOff <= src.length; //@ requires destOff >= 0 && destOff <= dest.length; //@ requires length + srcOff <= src.length; //@ requires length + destOff <= dest.length; // post: contenido de dest y src desde srcoff y destoff iguales private static void arraycopy(int[] src, int srcOff, int[] dest, int destOff, int length) { for( int i=0 ; i<length; i++) { dest[destOff+i] = src[srcOff+i]; } } }