sclass PosNeg { new MultiSet pos; new MultiSet neg; *() {} *(Iterable pos, Iterable neg) { this.pos.addAll(pos); this.neg.addAll(neg); } *(Iterable> pairs) { fOr (Pair p : pairs) add(p.a, p.b); } *(Map map) { fOr (A a, Bool b : map) add(a, b); } void add(A a, int score) { if (score > 0) pos.add(a, score); else if (score < 0) neg.add(a, -score); } void add(A a, Bool b) { if (isTrue(b)) pos.add(a); else if (isFalse(b)) neg.add(a); } int get(A a) { ret pos.get(a)-neg.get(a); } int score() { ret l(pos)-l(neg); } int n() { ret l(pos)+l(neg); } int nPos() { ret l(pos); } int nNeg() { ret l(neg); } bool isEmpty() { ret n() == 0; } bool perfect() { ret nPos() != 0 && nNeg() == 0; } bool antiPerfect() { ret nPos() == 0 && nNeg() != 0; } toString { ret "+" + nPos() + "/-" + nNeg() + ": " + pos + " / " + neg; } }