internal CharacterSet/*!*/ Union(CharacterSet/*!*/ set) { if (IsEmpty) { return set; } else if (set.IsEmpty) { return this; } if (_negated) { if (set._negated) { // ^A or ^B == ^(A and B) return Complement().Intersect(set.Complement()).Complement(); } else { // ^A or B == ^(A \ B) return Complement().Subtract(set).Complement(); } } else if (set._negated) { // A or ^B == ^(B \ A) return set.Complement().Subtract(this).Complement(); } // (a \ B) or (c \ D) == (a or c) \ ((D \ a) or (B \ c) or (B and D)) // // Proof: // (a \ B) or (c \ D) == // (a and ^B) or (c and ^D) == // (a or c) and (a or ^D) and (^B or c) and (^B or ^D) == // (a or c) \ (^(a or ^D) or ^(^B or c) or ^(^B or ^D)) == // (a or c) \ ((D \ a) or (B \ c) or (B and D)) QED return new CharacterSet(_include + set._include, set._exclude.Subtract(GetIncludedSet()). Union(this._exclude.Subtract(set.GetIncludedSet())). Union(this._exclude.Intersect(set._exclude)) ); }
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))); }
internal CharacterSet/*!*/ Subtract(CharacterSet/*!*/ set) { if (IsEmpty || set.IsEmpty) { return this; } if (_negated) { if (set._negated) { // (^A) \ (^B) = ^A and B = B \ A return set.Complement().Subtract(Complement()); } else { // (^A) \ B == ^(A or B) return Complement().Union(set).Complement(); } } else if (set._negated) { // A \ ^(B) == A and B return Intersect(set.Complement()); } // (a \ B) \ C == a \ (B or C) return new CharacterSet(_include, _exclude.Union(set)); }