コード例 #1
0
        public static StringDistribution SubAverageConditional(StringDistribution str, int start, int minLength, int maxLength)
        {
            Argument.CheckIfNotNull(str, "str");
            Argument.CheckIfInRange(start >= 0, "start", "Start index must be non-negative.");
            Argument.CheckIfInRange(minLength >= 0, "minLength", "Min length must be non-negative.");
            Argument.CheckIfInRange(maxLength >= 0, "maxLength", "Max length must be non-negative.");

            if (str.IsPointMass)
            {
                var strPoint = str.Point;
                var alts     = new HashSet <string>();
                for (int length = minLength; length <= maxLength; length++)
                {
                    var s = strPoint.Substring(start, Math.Min(length, strPoint.Length));
                    alts.Add(s);
                }
                return(StringDistribution.OneOf(alts));
            }

            var anyChar    = StringAutomaton.ConstantOnElement(1.0, ImmutableDiscreteChar.Any());
            var transducer = StringTransducer.Consume(StringAutomaton.Repeat(anyChar, minTimes: start, maxTimes: start));

            transducer.AppendInPlace(StringTransducer.Copy(StringAutomaton.Repeat(anyChar, minTimes: minLength, maxTimes: maxLength)));
            transducer.AppendInPlace(StringTransducer.Consume(StringAutomaton.Constant(1.0)));

            return(StringDistribution.FromWeightFunction(transducer.ProjectSource(str.ToAutomaton())));
        }
コード例 #2
0
        public void SampleGeometric()
        {
            Rand.Restart(96);

            const double StoppingProbability = 0.7;

            // The length of sequences sampled from this distribution must follow a geometric distribution
            StringAutomaton automaton = StringAutomaton.Zero();

            automaton.Start = automaton.AddState();
            automaton.Start.SetEndWeight(Weight.FromValue(StoppingProbability));
            automaton.Start.AddTransition('a', Weight.FromValue(1 - StoppingProbability), automaton.Start);
            StringDistribution dist = StringDistribution.FromWeightFunction(automaton);

            var       acc         = new MeanVarianceAccumulator();
            const int SampleCount = 30000;

            for (int i = 0; i < SampleCount; ++i)
            {
                string sample = dist.Sample();
                acc.Add(sample.Length);
            }

            const double ExpectedMean     = (1.0 - StoppingProbability) / StoppingProbability;
            const double ExpectedVariance = (1.0 - StoppingProbability) / (StoppingProbability * StoppingProbability);

            Assert.Equal(ExpectedMean, acc.Mean, 1e-2);
            Assert.Equal(ExpectedVariance, acc.Variance, 1e-2);
        }
コード例 #3
0
        public void LoopyArithmetic()
        {
            StringAutomaton automaton1 = StringAutomaton.Zero();

            automaton1.Start.AddTransition('a', Weight.FromValue(4.0)).AddTransition('b', Weight.One, automaton1.Start).EndWeight = Weight.One;

            StringAutomaton automaton2 = StringAutomaton.Zero();

            automaton2.Start.AddSelfTransition('a', Weight.FromValue(2)).AddSelfTransition('b', Weight.FromValue(3)).EndWeight = Weight.One;

            StringAutomaton sum = automaton1.Sum(automaton2);

            StringInferenceTestUtilities.TestValue(sum, 2.0, string.Empty);
            StringInferenceTestUtilities.TestValue(sum, 4.0 + 6.0, "ab");
            StringInferenceTestUtilities.TestValue(sum, 16.0 + 36.0, "abab");
            StringInferenceTestUtilities.TestValue(sum, 12.0, "aab", "aba", "baa");
            StringInferenceTestUtilities.TestValue(sum, 18.0, "abb", "bab", "bba");
            StringInferenceTestUtilities.TestValue(sum, 8.0, "aaa");
            StringInferenceTestUtilities.TestValue(sum, 27.0, "bbb");

            StringAutomaton product = automaton1.Product(automaton2);

            StringInferenceTestUtilities.TestValue(product, 1.0, string.Empty);
            StringInferenceTestUtilities.TestValue(product, 4 * 6, "ab");
            StringInferenceTestUtilities.TestValue(product, 16 * 36, "abab");
            StringInferenceTestUtilities.TestValue(product, 0.0, "aba", "bbb", "a", "b");

            product.SetToProduct(product, product);
            StringInferenceTestUtilities.TestValue(product, 1.0, string.Empty);
            StringInferenceTestUtilities.TestValue(product, 4 * 4 * 6 * 6, "ab");
            StringInferenceTestUtilities.TestValue(product, 16 * 16 * 36 * 36, "abab");
            StringInferenceTestUtilities.TestValue(product, 0.0, "aba", "bbb", "a", "b");
        }
コード例 #4
0
        public void NoPoint1()
        {
            StringAutomaton f = StringAutomaton.Zero();

            f.Start.AddTransition('a', Weight.FromValue(0.5)).AddTransition('b', Weight.FromValue(0.5), f.Start).EndWeight = Weight.One;
            Assert.Null(f.TryComputePoint());
        }
コード例 #5
0
        public void Transpose()
        {
            StringTransducer transducer = StringTransducer.Consume(StringAutomaton.Constant(3.0));
            StringTransducer transpose1 = StringTransducer.Transpose(transducer);
            StringTransducer transpose2 = transducer.Clone();

            transpose2.TransposeInPlace();

            var pairs = new[]
            {
                new[] { "a", string.Empty },
                new[] { string.Empty, string.Empty },
                new[] { "a", "bc" },
                new[] { "a", "a" }
            };

            foreach (string[] valuePair in pairs)
            {
                double referenceValue1 = transducer.GetValue(valuePair[0], valuePair[1]);
                Assert.Equal(referenceValue1, transpose1.GetValue(valuePair[1], valuePair[0]));
                Assert.Equal(referenceValue1, transpose2.GetValue(valuePair[1], valuePair[0]));

                double referenceValue2 = transducer.GetValue(valuePair[1], valuePair[0]);
                Assert.Equal(referenceValue2, transpose1.GetValue(valuePair[0], valuePair[1]));
                Assert.Equal(referenceValue2, transpose2.GetValue(valuePair[0], valuePair[1]));
            }
        }
コード例 #6
0
        public void Copy()
        {
            StringTransducer copy = StringTransducer.Copy();

            StringInferenceTestUtilities.TestTransducerValue(copy, "important", "important", 1.0);
            StringInferenceTestUtilities.TestTransducerValue(copy, "important", "i", 0.0);
            StringInferenceTestUtilities.TestTransducerValue(copy, "important", "imp", 0.0);
            StringInferenceTestUtilities.TestTransducerValue(copy, "important", "t", 0.0);
            StringInferenceTestUtilities.TestTransducerValue(copy, "important", "mpo", 0.0);
            StringInferenceTestUtilities.TestTransducerValue(copy, string.Empty, string.Empty, 1.0);
            StringInferenceTestUtilities.TestTransducerValue(copy, "important", string.Empty, 0.0);
            StringInferenceTestUtilities.TestTransducerValue(copy, string.Empty, "important", 0.0);

            //// Test that projection on Copy() doesn't change the automaton

            StringAutomaton automaton = StringAutomaton.ConstantOn(2.0, "a", "ab", "ac");

            automaton = automaton.Sum(StringAutomaton.ConstantOn(1.0, "a"));
            automaton = automaton.Sum(StringAutomaton.Constant(2.0));
            automaton = automaton.Product(StringAutomaton.Constant(3.0));

            StringAutomaton automatonClone = copy.ProjectSource(automaton);

            Assert.Equal(automaton, automatonClone);
        }
コード例 #7
0
        public void CopyElement()
        {
            StringTransducer copy = StringTransducer.CopyElement(DiscreteChar.OneOf('a', 'b'));

            StringInferenceTestUtilities.TestTransducerValue(copy, "a", "a", 1.0);
            StringInferenceTestUtilities.TestTransducerValue(copy, "b", "b", 1.0);
            StringInferenceTestUtilities.TestTransducerValue(copy, "a", "b", 0.0);
            StringInferenceTestUtilities.TestTransducerValue(copy, "b", "a", 0.0);
            StringInferenceTestUtilities.TestTransducerValue(copy, string.Empty, string.Empty, 0.0);
            StringInferenceTestUtilities.TestTransducerValue(copy, "bb", "bb", 0.0);
            StringInferenceTestUtilities.TestTransducerValue(copy, "bab", "bab", 0.0);
            StringInferenceTestUtilities.TestTransducerValue(copy, "bab", "ba", 0.0);

            //// Tests that projection on CopyElement(elements) shrinks the support

            StringAutomaton automaton = StringAutomaton.ConstantOn(2.0, "a", "ab", "ac");

            automaton = automaton.Sum(StringAutomaton.ConstantOn(1.0, "a"));
            automaton = automaton.Sum(StringAutomaton.Constant(2.0));
            automaton = automaton.Product(StringAutomaton.Constant(3.0));

            for (int i = 0; i < 2; ++i)
            {
                StringInferenceTestUtilities.TestValue(automaton, 15, "a");
                StringInferenceTestUtilities.TestValue(automaton, 6.0, "b");
                StringInferenceTestUtilities.TestValue(automaton, i == 0 ? 6.0 : 0.0, string.Empty);
                StringInferenceTestUtilities.TestValue(automaton, i == 0 ? 12.0 : 0.0, "ac", "ab");

                automaton = copy.ProjectSource(automaton);
            }
        }
コード例 #8
0
        /// <summary>EP message to <c>str</c>.</summary>
        /// <param name="format">Incoming message from <c>format</c>.</param>
        /// <param name="args">Incoming message from <c>args</c>.</param>
        /// <returns>The outgoing EP message to the <c>str</c> argument.</returns>
        /// <remarks>
        ///   <para>The outgoing message is a distribution matching the moments of <c>str</c> as the random arguments are varied. The formula is <c>proj[p(str) sum_(format,args) p(format,args) factor(str,format,args)]/p(str)</c>.</para>
        /// </remarks>
        public static StringDistribution StrAverageConditional(StringDistribution format, IList <StringDistribution> args)
        {
            Argument.CheckIfNotNull(format, "format");
            Argument.CheckIfNotNull(args, "args");
            Argument.CheckIfValid(args.Count > 0, "args", "There must be at least one argument provided."); // TODO: relax?

            if (args.Count >= 10)
            {
                throw new NotImplementedException("Up to 10 arguments currently supported.");
            }

            // Disallow special characters in args or format
            StringAutomaton        result      = DisallowBraceReplacersTransducer.ProjectSource(format);
            List <StringAutomaton> escapedArgs = args.Select(DisallowBraceReplacersTransducer.ProjectSource).ToList();

            // Check braces for correctness and replace them with special characters.
            // Also, make sure that each argument placeholder is present exactly once.
            // Superposition of transducers is used instead of a single transducer to allow for any order of arguments.
            // TODO: in case of a single argument, argument escaping stage can be skipped
            for (int i = 0; i < args.Count; ++i)
            {
                result = GetArgumentEscapingTransducer(i, args.Count, false).ProjectSource(result);
            }

            // Now replace placeholders with arguments
            result = GetPlaceholderReplacingTransducer(escapedArgs, false).ProjectSource(result);
            return(StringDistribution.FromWorkspace(result));
        }
コード例 #9
0
        /// <summary>EP message to <c>format</c>.</summary>
        /// <param name="str">Incoming message from <c>str</c>.</param>
        /// <param name="args">Incoming message from <c>args</c>.</param>
        /// <returns>The outgoing EP message to the <c>format</c> argument.</returns>
        /// <remarks>
        ///   <para>The outgoing message is a distribution matching the moments of <c>format</c> as the random arguments are varied. The formula is <c>proj[p(format) sum_(str,args) p(str,args) factor(str,format,args)]/p(format)</c>.</para>
        /// </remarks>
        public static StringDistribution FormatAverageConditional(StringDistribution str, IList <StringDistribution> args)
        {
            Argument.CheckIfNotNull(str, "str");
            Argument.CheckIfNotNull(args, "args");
            Argument.CheckIfValid(args.Count > 0, "args", "There must be at least one argument provided."); // TODO: relax?

            if (args.Count >= 10)
            {
                throw new NotImplementedException("Up to 10 arguments currently supported.");
            }

            // Disallow special characters in args
            List <StringAutomaton> escapedArgs = args.Select(DisallowBraceReplacersTransducer.ProjectSource).ToList();

            // Reverse the process defined by StrAverageConditional
            StringAutomaton result = GetPlaceholderReplacingTransducer(escapedArgs, true).ProjectSource(str);

            for (int i = 0; i < args.Count; ++i)
            {
                result = GetArgumentEscapingTransducer(i, args.Count, true).ProjectSource(result);
            }

            result = DisallowBraceReplacersTransducer.ProjectSource(result);
            return(StringDistribution.FromWorkspace(result));
        }
コード例 #10
0
        public void ComputeNormalizerWithManyNonTrivialLoops2()
        {
            StringAutomaton automaton = StringAutomaton.Zero();

            automaton.AddStates(6);

            automaton.States[0].AddEpsilonTransition(Weight.FromValue(0.2), automaton.States[1]);
            automaton.States[0].AddEpsilonTransition(Weight.FromValue(0.5), automaton.States[3]);
            automaton.States[0].EndWeight = Weight.FromValue(0.3);
            automaton.States[1].AddEpsilonTransition(Weight.FromValue(0.8), automaton.States[0]);
            automaton.States[1].AddEpsilonTransition(Weight.FromValue(0.1), automaton.States[2]);
            automaton.States[1].EndWeight = Weight.FromValue(0.1);
            automaton.States[2].EndWeight = Weight.FromValue(1.0);
            automaton.States[3].AddEpsilonTransition(Weight.FromValue(0.2), automaton.States[4]);
            automaton.States[3].AddEpsilonTransition(Weight.FromValue(0.1), automaton.States[5]);
            automaton.States[3].EndWeight = Weight.FromValue(0.7);
            automaton.States[4].AddEpsilonTransition(Weight.FromValue(0.5), automaton.States[2]);
            automaton.States[4].AddEpsilonTransition(Weight.FromValue(0.5), automaton.States[6]);
            automaton.States[4].EndWeight = Weight.FromValue(0.0);
            automaton.States[5].AddEpsilonTransition(Weight.FromValue(0.1), automaton.States[3]);
            automaton.States[5].AddEpsilonTransition(Weight.FromValue(0.9), automaton.States[6]);
            automaton.States[5].EndWeight = Weight.Zero;
            automaton.States[6].EndWeight = Weight.One;

            AssertStochastic(automaton);
            Assert.Equal(0.0, automaton.GetLogNormalizer(), 1e-6);
            Assert.Equal(0.0, GetLogNormalizerByGetValue(automaton), 1e-6);
            Assert.Equal(0.0, GetLogNormalizerByGetValueWithTransducers(automaton), 1e-6);
        }
コード例 #11
0
        /// <summary>
        /// Computes the normalizer of an automaton by replacing every transition with an epsilon transition
        /// and computing the value of the automaton on an empty sequence.
        /// </summary>
        /// <param name="automaton">The automaton.</param>
        /// <returns>The logarithm of the normalizer.</returns>
        private static double GetLogNormalizerByGetValue(StringAutomaton automaton)
        {
            var epsilonAutomaton = new StringAutomaton();

            epsilonAutomaton.SetToFunction(automaton, (dist, weight, group) => ValueTuple.Create <Option <DiscreteChar>, Weight>(Option.None, weight)); // Convert all the edges to epsilon edges
            return(epsilonAutomaton.GetLogValue(string.Empty));                                                                                         // Now this will be exactly the normalizer
        }
コード例 #12
0
        public void PointMassDetectionWithEpsilonLoop()
        {
            StringAutomaton f = StringAutomaton.Zero();

            AddEpsilonLoop(f.Start, 5, 0.5);
            f.Start.AddTransitionsForSequence("abc").EndWeight = Weight.One;
            Assert.Equal("abc", f.TryComputePoint());
        }
コード例 #13
0
        /// <summary>
        /// Computes the normalizer via transducers.
        /// </summary>
        /// <param name="automaton">The automaton.</param>
        /// <returns>The logarithm of the normalizer.</returns>
        private static double GetLogNormalizerByGetValueWithTransducers(StringAutomaton automaton)
        {
            var one = StringAutomaton.Constant(1.0);
            StringTransducer transducer = StringTransducer.Consume(automaton);

            transducer.AppendInPlace(StringTransducer.Produce(one));
            return(transducer.ProjectSource(one).GetLogValue("an arbitrary string")); // Now this will be exactly the normalizer
        }
コード例 #14
0
        /// <summary>
        /// Tests if a projection of a given automaton onto a given transducer has the desired value on a given sequence.
        /// </summary>
        /// <param name="transducer">The transducer.</param>
        /// <param name="input">The automaton to project.</param>
        /// <param name="str">The sequence to test the projection on.</param>
        /// <param name="trueValue">The desired value of the projection on the sequence.</param>
        public static void TestTransducerProjection(
            StringTransducer transducer, StringAutomaton input, string str, double trueValue)
        {
            // Test ProjectSource(func)
            var result = transducer.ProjectSource(input);

            TestValue(result, trueValue, str);
        }
コード例 #15
0
        /// <summary>
        /// Computes the normalizer of an automaton by replacing every transition with an epsilon transition
        /// and computing the value of the automaton on an empty sequence.
        /// </summary>
        /// <param name="automaton">The automaton.</param>
        /// <returns>The logarithm of the normalizer.</returns>
        private static double GetLogNormalizerByGetValue(StringAutomaton automaton)
        {
            var epsilonAutomaton = new StringAutomaton();

            epsilonAutomaton = automaton.ApplyFunction <string, char, ImmutableDiscreteChar, StringManipulator, StringAutomaton>(
                (dist, weight, group) => ValueTuple.Create <Option <ImmutableDiscreteChar>, Weight>(Option.None, weight)); // Convert all the edges to epsilon edges
            return(epsilonAutomaton.GetLogValue(string.Empty));                                                            // Now this will be exactly the normalizer
        }
コード例 #16
0
        public void PointMassDetectionLoopInDeadEnd()
        {
            StringAutomaton f = StringAutomaton.Zero();

            f.Start.AddTransition('a', Weight.FromValue(0.5)).AddSelfTransition('a', Weight.FromValue(0.5)).AddTransition('b', Weight.One);
            f.Start.AddTransition('b', Weight.FromValue(0.5)).EndWeight = Weight.One;
            Assert.Equal("b", f.TryComputePoint());
        }
コード例 #17
0
        public void PointMassDetectionWithDeadLoop()
        {
            StringAutomaton f = StringAutomaton.Zero();

            f.Start.AddTransition('a', Weight.FromValue(0.5)).AddTransition('b', Weight.Zero, f.Start);
            f.Start.AddTransitionsForSequence("abc").EndWeight = Weight.One;
            Assert.Equal("abc", f.TryComputePoint());
        }
コード例 #18
0
        public void ZeroDetectionWithDeadSelfLoop()
        {
            StringAutomaton f = StringAutomaton.Zero();

            f.Start.AddSelfTransition('x', Weight.Zero);
            f.Start.AddTransition('y', Weight.Zero).EndWeight = Weight.One;
            Assert.True(f.IsZero());
        }
コード例 #19
0
        public void ZeroDetectionWithEpsilonLoop1()
        {
            StringAutomaton f = StringAutomaton.Zero();

            AddEpsilonLoop(f.Start, 5, 0);
            Assert.False(f.IsCanonicZero());
            Assert.True(f.IsZero());
        }
コード例 #20
0
        public void NoPoint2()
        {
            StringAutomaton f     = StringAutomaton.Zero();
            var             state = f.Start.AddTransition('a', Weight.FromValue(0.5));

            state.SetEndWeight(Weight.One);
            state.AddTransition('b', Weight.FromValue(0.5), f.Start);
            Assert.Null(f.TryComputePoint());
        }
コード例 #21
0
 /// <summary>
 /// Tests whether the logarithm of the value of a given automaton on given strings equals to a specified value.
 /// </summary>
 /// <param name="automaton">The automaton.</param>
 /// <param name="trueLogValue">The expected logarithm of the function value.</param>
 /// <param name="strings">The strings to test.</param>
 public static void TestLogValue(StringAutomaton automaton, double trueLogValue, params string[] strings)
 {
     foreach (string str in strings)
     {
         double logValue = automaton.GetLogValue(str);
         Assert.Equal(trueLogValue, logValue, LogValueEps);
         Assert.Equal(logValue, Clone(automaton).GetLogValue(str));
     }
 }
コード例 #22
0
        public void ZeroDetectionWithEpsilonLoop2()
        {
            StringAutomaton f = StringAutomaton.Zero();

            AddEpsilonLoop(f.Start, 5, 2.0);
            f.Start.AddTransition('a', Weight.One);
            Assert.False(f.IsCanonicZero());
            Assert.True(f.IsZero());
        }
コード例 #23
0
        public void ConvertToStringWithLoops4()
        {
            StringAutomaton automaton = StringAutomaton.Zero();

            automaton.Start.AddTransitionsForSequence("xyz", automaton.Start);
            automaton.Start.AddTransition('!', Weight.One).EndWeight = Weight.One;
            Assert.Equal("(xyz)*!", automaton.ToString(AutomatonFormats.Friendly));
            Assert.Equal("(xyz)*!", automaton.ToString(AutomatonFormats.Regexp));
        }
コード例 #24
0
        public void PointMassDetection()
        {
            StringDistribution s1     = StringDistribution.OneOf("hello", "world", "people");
            StringDistribution s2     = StringDistribution.OneOf("greetings", "people", "animals");
            StringDistribution point1 = s1.Product(s2);

            Assert.True(point1.IsPointMass);
            Assert.Equal("people", point1.Point);

            StringDistribution point2 = StringDistribution.OneOf(new Dictionary <string, double> {
                { "a", 3.0 }, { "b", 0.0 }
            });

            Assert.True(point2.IsPointMass);
            Assert.Equal("a", point2.Point);

            StringDistribution point3 = StringDistribution.CaseInvariant("123");

            Assert.True(point3.IsPointMass);
            Assert.Equal("123", point3.Point);

            StringDistribution point4 = StringDistribution.Char('Z');

            Assert.True(point4.IsPointMass);
            Assert.Equal("Z", point4.Point);

            StringDistribution point5 = StringDistribution.OneOf(1.0, StringDistribution.String("!"), 0.0, StringDistribution.Any());

            Assert.True(point5.IsPointMass);
            Assert.Equal("!", point5.Point);

            StringDistribution point6 = StringDistribution.Repeat('@', minTimes: 3, maxTimes: 3);

            Assert.True(point6.IsPointMass);
            Assert.Equal("@@@", point6.Point);

            StringDistribution point7 = StringDistribution.String("hello").Append(StringDistribution.String(" world"));

            Assert.True(point7.IsPointMass);
            Assert.Equal("hello world", point7.Point);

            string          point           = string.Empty;
            StringAutomaton point8Automaton = StringAutomaton.Empty();

            for (int i = 0; i < 22; ++i)
            {
                const string PointElement = "a";
                point8Automaton.AppendInPlace(StringAutomaton.ConstantOn(1.0, PointElement, PointElement));
                point += PointElement;
            }

            StringDistribution point8 = StringDistribution.FromWeightFunction(point8Automaton);

            Assert.True(point8.IsPointMass);
            Assert.Equal(point, point8.Point);
        }
コード例 #25
0
        /// <summary>
        /// Creates an automaton for validating the correctness of argument placeholders for a given argument.
        /// </summary>
        /// <param name="argToValidateIndex">The index of the argument to validate.</param>
        /// <param name="argNames">The names of all arguments.</param>
        /// <returns>The created automaton.</returns>
        private static StringAutomaton GetArgumentValidatingAutomaton(int argToValidateIndex, IReadOnlyList <string> argNames)
        {
            Debug.Assert(
                argNames != null && argNames.All(name => !string.IsNullOrEmpty(name)),
                "A valid array of argument names must be provided.");
            Debug.Assert(
                argToValidateIndex >= 0 && argToValidateIndex < argNames.Count,
                "The provided argument index must be a valid index in the argument name array.");

            string          argListKey = ArgumentListToDictionaryKey(argToValidateIndex, argNames);
            StringAutomaton result;

            if (ArgsToValidatingAutomaton.TryGetValue(argListKey, out result))
            {
                return(result);
            }

            // Accepts placeholder for the current argument
            StringAutomaton checkBracesForCurrentArg = StringAutomaton.ConstantOn(1.0, "{" + argNames[argToValidateIndex] + "}");

            StringAutomaton checkBracesForOtherArgs = DisallowBracesAutomaton.Clone();

            if (argNames.Count > 1)
            {
                // Skips placeholders for every argument except the current one
                StringAutomaton skipOtherArgs = StringAutomaton.ConstantOnElement(1.0, '{');
                skipOtherArgs.AppendInPlace(StringAutomaton.ConstantOn(1.0, argNames.Where((arg, index) => index != argToValidateIndex)));
                skipOtherArgs.AppendInPlace(StringAutomaton.ConstantOnElement(1.0, '}'));

                // Accepts placeholders for arguments other than current, with arbitrary intermediate text
                checkBracesForOtherArgs.AppendInPlace(skipOtherArgs);
                checkBracesForOtherArgs = StringAutomaton.Repeat(checkBracesForOtherArgs, minTimes: 0);
                checkBracesForOtherArgs.AppendInPlace(DisallowBracesAutomaton);
            }

            // Checks the placeholder for the current argument, then skips placeholders for other arguments
            StringAutomaton validateArgumentThenOtherArguments = checkBracesForCurrentArg.Clone();

            validateArgumentThenOtherArguments.AppendInPlace(checkBracesForOtherArgs);
            if (!RequirePlaceholderForEveryArgument)
            {
                // Make this block optional
                validateArgumentThenOtherArguments = StringAutomaton.Sum(
                    validateArgumentThenOtherArguments,
                    StringAutomaton.ConstantOn(1.0, string.Empty));
            }

            // Accepts placeholders for arguments other then current, then for the current argument, then again other placeholders
            result = checkBracesForOtherArgs.Clone();
            result.AppendInPlace(validateArgumentThenOtherArguments);

            result.TryDeterminize();
            ArgsToValidatingAutomaton[argListKey] = result;

            return(result);
        }
コード例 #26
0
        public void ParseInvalid_StringAutomaton()
        {
            bool expected = false;

            string s = "Not a valid string";

            bool actual = StringAutomaton.Parse(s);

            Assert.AreEqual(expected, actual);
        }
コード例 #27
0
 /// <summary>
 /// Tests if a transducer projects each of given strings to a zero function.
 /// </summary>
 /// <param name="transducer">The transducer.</param>
 /// <param name="strings">The strings to test.</param>
 public static void TestIfTransducerRejects(StringTransducer transducer, params string[] strings)
 {
     foreach (string str in strings)
     {
         var res = transducer.ProjectSource(StringAutomaton.ConstantOn(1.0, str));
         Assert.True(res.IsZero());
         var res2 = transducer.ProjectSource(str);
         Assert.True(res2.IsZero());
     }
 }
コード例 #28
0
        public void ConvertToStringWithDeadTransitions2()
        {
            StringAutomaton automaton = StringAutomaton.Zero();

            automaton.Start.AddSelfTransition('x', Weight.Zero);
            automaton.Start.AddTransition('y', Weight.Zero).EndWeight = Weight.One;

            Assert.Equal("Ø", automaton.ToString(AutomatonFormats.Friendly));
            Assert.Equal("Ø", automaton.ToString(AutomatonFormats.Regexp));
        }
コード例 #29
0
        public void Repeat4()
        {
            StringAutomaton automaton = StringAutomaton.ConstantOn(2.0, "aa");

            automaton = StringAutomaton.Repeat(automaton, minTimes: 0);

            StringInferenceTestUtilities.TestValue(automaton, 0.0, "a", "aaa");
            StringInferenceTestUtilities.TestValue(automaton, 1.0, string.Empty);
            StringInferenceTestUtilities.TestValue(automaton, 2.0, "aa");
            StringInferenceTestUtilities.TestValue(automaton, 4.0, "aaaa");
        }
コード例 #30
0
        public void ConvertToStringWithLoops2()
        {
            StringAutomaton automaton = StringAutomaton.Zero();

            automaton.Start.AddSelfTransition('a', Weight.One);
            automaton.Start.AddSelfTransition('b', Weight.One);
            automaton.Start.EndWeight = Weight.One;

            Assert.Equal("(a|b)*", automaton.ToString(AutomatonFormats.Friendly));
            Assert.Equal("(a|b)*", automaton.ToString(AutomatonFormats.Regexp));
        }