internal CharacterSet/*!*/ Intersect(CharacterSet/*!*/ set) {
if (IsEmpty || set.IsEmpty) {
return Empty;
}
if (_negated) {
if (set._negated) {
// ^A and ^B == ^(A or B)
return Complement().Union(set.Complement()).Complement();
} else {
// ^A and B = B \ A
return set.Subtract(Complement());
}
} else if (set._negated) {
// A and ^B = A \ B
return Subtract(set.Complement());
}
// (a \ B) and (c \ D) == a \ ^(c \ (B or D))
//
// Proof:
// (a \ B) and (c \ D) ==
// (a and ^B) and (c and ^D) ==
// a \ ^(c and ^B and ^D) ==
// a \ ^(c \ (B or D)) QED
return new CharacterSet(_include, new CharacterSet(true, set._include, _exclude.Union(set._exclude)));
}