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;
}
}