/// <summary> /// Creates a uniform distribution over any string starting and ending with a non-word character, /// with a length in given bounds. /// Characters other than the first and the last are restricted to be non-zero probability characters /// from a given distribution. /// </summary> /// <param name="minLength">The minimum allowed string length.</param> /// <param name="maxLength">The maximum allowed string length.</param> /// <param name="allowedChars">The distribution representing allowed characters.</param> /// <returns>The created distribution.</returns> public static StringDistribution WordMiddle(int minLength, int maxLength, DiscreteChar allowedChars) { if (maxLength < minLength) { throw new ArgumentException("The maximum length cannot be less than the minimum length."); } if (minLength < 1) { throw new ArgumentException("The minimum length must be at least one."); } var nonWordChar = StringDistribution.Char(NonWordCharacter); if ((minLength == 1) && (maxLength == 1)) { return(nonWordChar); } // TODO: make a PartialUniform copy of allowedChars var suffix = StringDistribution.Repeat(allowedChars, minTimes: Math.Max(minLength - 2, 0), maxTimes: maxLength - 2); suffix.AppendInPlace(nonWordChar); if (minLength == 1) { var allowedChar = allowedChars.GetMode(); var allowedSuffix = new string(Enumerable.Repeat(allowedChar, Math.Max(minLength - 2, 0)).ToArray()) + ' '; var suffixLogProb = suffix.GetLogProb(allowedSuffix); suffix.SetToSumLog(suffixLogProb, StringDistribution.Empty(), 0.0, suffix); } return(nonWordChar + suffix); }