import java.util.Set; import java.util.Iterator; import pt.ist.esw.atomicannotation.Atomic; import jvstm.VBox; import jvstm.VBoxInt; import jvstm.util.VLinkedSet; import jvstm.cps.ConsistencyException; import jvstm.cps.ConsistencyPredicate; import jvstm.cps.ConsistencyPredicateSystem; public class SimpleTests { public static void main(String[] args) { ConsistencyPredicateSystem.initialize(); SimpleTests tests = new SimpleTests(); tests.run(); } public void run() { BagOfValues bag = makeBag(); addToBag(bag, NUMBER_CREATOR, 1, 2, 3, 4); addToBag(bag, EVEN_CREATOR, 2, 4, 6, 8); addToBag(bag, EVEN_CREATOR, 1, 2, 3); addToBag(bag, NUMBER_CREATOR, -100); addToBag(bag, NUMBER_CREATOR, 2000); addToBag(bag, NUMBER_CREATOR, -100); addToBag(bag, NUMBER_CREATOR, -1500); addToBag(bag, EVEN_CREATOR, 10, 20, 30, 15); addToValue(bag, 2000, 100); addToValue(bag, -100, -300); addToValue(bag, 8, 1); addToValue(bag, 2100, -100); addToValue(bag, -400, -700); addToValue(bag, 6, 10); addToValue(bag, 2000, -2000); addToValue(bag, 16, 10); removeValue(bag, 26); removeValue(bag, 2000); removeValue(bag, 1); addToBag(bag, NUMBER_CREATOR, 500, 600, 700); removeValue(bag, 2000); removeValue(bag, -400); removeValue(bag, 0); } @Atomic public BagOfValues makeBag() { return new BagOfValues(); } public void removeValue(BagOfValues bag, int value) { bag.printSummary(); System.out.printf("Will try to remove the value %d\n", value); try { atomicRemoveValue(bag, value); System.out.println("+++++ It worked!"); } catch (ConsistencyException ce) { System.out.println("----- Failed because of a consistency exception: " + ce.getMethodName()); } } @Atomic public void atomicRemoveValue(BagOfValues bag, int value) { Iterator<Number> iter = bag.getNumbers().iterator(); while (iter.hasNext()) { if (iter.next().getValue() == value) { iter.remove(); return; } } } public void addToValue(BagOfValues bag, int value, int valueToAdd) { bag.printSummary(); System.out.printf("Will try to add %d to the value %d\n", valueToAdd, value); try { atomicAddToValue(bag, value, valueToAdd); System.out.println("+++++ It worked!"); } catch (ConsistencyException ce) { System.out.println("----- Failed because of a consistency exception: " + ce.getMethodName()); } } @Atomic public void atomicAddToValue(BagOfValues bag, int value, int valueToAdd) { for (Number num : bag.getNumbers()) { if (num.getValue() == value) { num.update(valueToAdd); return; } } } public void addToBag(BagOfValues bag, NumCreator numCreator, Integer... values) { bag.printSummary(); System.out.printf("Will try to add %s elements with values: ", numCreator.name()); for (int val : values) { System.out.printf("%d, ", val); } System.out.println(); try { atomicAdd(bag, numCreator, values); System.out.println("+++++ It worked!"); } catch (ConsistencyException ce) { System.out.println("----- Failed because of a consistency exception: " + ce.getMethodName()); } } @Atomic public void atomicAdd(BagOfValues bag, NumCreator numCreator, Integer[] values) { for (Integer val : values) { bag.addValue(numCreator.create(val)); } } interface NumCreator { public Number create(int value); public String name(); } static final NumCreator NUMBER_CREATOR = new NumCreator() { public Number create(int val) { return new Number(val); } public String name() { return "Number"; } }; static final NumCreator EVEN_CREATOR = new NumCreator() { public Number create(int val) { return new Even(val); } public String name() { return "Even"; } }; static class Number { private VBoxInt value = new VBoxInt(0); public Number(int value) { ConsistencyPredicateSystem.registerNewObject(this); this.value.putInt(value); } public void update(int delta) { this.value.inc(delta); } public int getValue() { return this.value.getInt(); } @ConsistencyPredicate public boolean greaterThanMinus1000() { return (getValue() > -1000); } } static class Even extends Number { public Even(int value) { super(value); } @ConsistencyPredicate public boolean isEven() { return (getValue() % 2) == 0; } } static class BagOfValues { private VLinkedSet<Number> values = new VLinkedSet<Number>(); public BagOfValues() { ConsistencyPredicateSystem.registerNewObject(this); } public void addValue(Number value) { this.values.add(value); } public Set<Number> getNumbers() { return values; } public int getTotal() { int total = 0; for (Number num : values) { total += num.getValue(); } return total; } public void printSummary() { System.out.printf("Current bag total value is: %d (", getTotal()); for (Number val : values) { System.out.printf("%d, ", val.getValue()); } System.out.println(")"); } @ConsistencyPredicate public boolean nonNegative() { return (getTotal() >= 0); } } }