/// <summary>Create a Boolean classifier.</summary> /// <param name="solver">Character algebra (the algebra is not stored in the classifier)</param> /// <param name="bdd">Elements that map to true.</param> public BooleanClassifier(CharSetSolver solver, BDD bdd) { // We want to optimize for ASCII, so query the BDD for each ASCII character in // order to precompute a lookup table we'll use at match time. var ascii = new bool[128]; for (int i = 0; i < ascii.Length; i++) { ascii[i] = bdd.Contains(i); } // At this point, we'll never consult the BDD for ASCII characters, so as an // optimization we can remove them from the BDD in hopes of simplifying it and making // it faster to query for the non-ASCII characters we will use it for. However, while // this is typically an optimization, it isn't always: the act of removing some // characters from the BDD can actually make the branching more complicated. The // extreme case of this is when the BDD is True, meaning everything maps to True, which // is as simple a BDD as you can get. In such a case, even though it's rare, this would // definitively be a deoptimization, so we avoid doing so. Other trivial cases are handled // by And itself, e.g. if the BDD == False, then And will just return False. if (!bdd.IsFull) { bdd = solver.And(solver._nonAscii, bdd); } _ascii = ascii; _nonAscii = bdd; }
public bool IsTrue(char c) { bool[] ascii = _ascii; return(c < ascii.Length ? ascii[c] : _nonAscii.Contains(c)); }