Ejemplo n.º 1
0
        /// <summary>
        /// Creates a transducer that replaces escaped argument placeholders with the corresponding arguments.
        /// </summary>
        /// <param name="escapedArgs">The list of arguments.</param>
        /// <param name="transpose">Specifies whether the created transducer should be transposed (useful for backward message computation).</param>
        /// <returns>The created transducer.</returns>
        private static StringTransducer GetPlaceholderReplacingTransducer(IList <StringAutomaton> escapedArgs, bool transpose)
        {
            var alternatives = new List <StringTransducer>();

            for (int i = 0; i < escapedArgs.Count; ++i)
            {
                StringTransducer alternative = StringTransducer.ConsumeElement((char)('0' + i));
                alternative.AppendInPlace(StringTransducer.Produce(escapedArgs[i]), (byte)(i + 1));
                alternatives.Add(alternative);
            }

            StringTransducer result = DisallowBraceReplacersTransducer.Clone();

            result.AppendInPlace(StringTransducer.ConsumeElement(LeftBraceReplacer));
            result.AppendInPlace(StringTransducer.Sum(alternatives));
            result.AppendInPlace(StringTransducer.ConsumeElement(RightBraceReplacer));
            result = StringTransducer.Repeat(result, minTimes: 0);
            result.AppendInPlace(DisallowBraceReplacersTransducer);

            if (transpose)
            {
                result.TransposeInPlace();
            }

            return(result);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates a transducer that replaces braces surrounding the given argument placeholder
        /// with <see cref="LeftBraceReplacer"/> and <see cref="RightBraceReplacer"/>.
        /// </summary>
        /// <param name="argument">The index of the argument.</param>
        /// <param name="argumentCount">The total number of the arguments.</param>
        /// <param name="transpose">Specifies whether the created transducer should be transposed (useful for backward message computation).</param>
        /// <returns>The created transducer.</returns>
        private static StringTransducer GetArgumentEscapingTransducer(int argument, int argumentCount, bool transpose)
        {
            Debug.Assert(argumentCount >= 1 && argumentCount <= 10, "Up to 10 arguments currently supported.");
            Debug.Assert(argument >= 0 && argument < argumentCount, "Argument index must be less than the number of arguments.");

            List <Pair <StringTransducer, StringTransducer> > argumentToEscapingTransducers;

            if (!ArgumentCountToEscapingTransducers.TryGetValue(argumentCount, out argumentToEscapingTransducers))
            {
                argumentToEscapingTransducers = new List <Pair <StringTransducer, StringTransducer> >(argumentCount);
                ArgumentCountToEscapingTransducers[argumentCount] = argumentToEscapingTransducers;

                for (int i = 0; i < argumentCount; ++i)
                {
                    // Escapes braces in {i}
                    StringTransducer replaceBracesForDigit = StringTransducer.ConsumeElement('{');
                    replaceBracesForDigit.AppendInPlace(StringTransducer.ProduceElement(LeftBraceReplacer));
                    replaceBracesForDigit.AppendInPlace(StringTransducer.CopyElement((char)('0' + i)));
                    replaceBracesForDigit.AppendInPlace(StringTransducer.ConsumeElement('}'));
                    replaceBracesForDigit.AppendInPlace(StringTransducer.ProduceElement(RightBraceReplacer));

                    // Skips any number of placeholders which differ from {i}, with arbitrary intermediate text
                    DiscreteChar     noBraces      = DiscreteChar.UniformOver('{', '}').Complement();
                    StringTransducer braceReplacer = StringTransducer.Copy(noBraces);
                    if (argumentCount > 1)
                    {
                        // Skips every placeholder except {i}
                        StringTransducer skipOtherDigits = StringTransducer.CopyElement('{');
                        skipOtherDigits.AppendInPlace(StringTransducer.CopyElement(AllDigitsExcept(i, argumentCount - 1)));
                        skipOtherDigits.AppendInPlace(StringTransducer.CopyElement('}'));

                        braceReplacer.AppendInPlace(skipOtherDigits);
                        braceReplacer = StringTransducer.Repeat(braceReplacer, minTimes: 0);
                        braceReplacer.AppendInPlace(StringTransducer.Copy(noBraces));
                    }

                    // Skips placeholders, then escapes {i} and skips placeholders
                    StringTransducer escapeAndSkip = replaceBracesForDigit.Clone();
                    escapeAndSkip.AppendInPlace(braceReplacer);
                    StringTransducer transducer = braceReplacer.Clone();
                    transducer.AppendInPlace(escapeAndSkip);  // TODO: use Optional() here if {i} can be omitted

                    StringTransducer transducerTranspose = StringTransducer.Transpose(transducer);
                    argumentToEscapingTransducers.Add(Pair.Create(transducer, transducerTranspose));
                }
            }

            return(transpose ? argumentToEscapingTransducers[argument].Second : argumentToEscapingTransducers[argument].First);
        }
Ejemplo n.º 3
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
        }
Ejemplo n.º 4
0
        /// <summary>EP message to <c>str2</c>.</summary>
        /// <param name="concat">Incoming message from <c>concat</c>.</param>
        /// <param name="str1">Incoming message from <c>str1</c>.</param>
        /// <returns>The outgoing EP message to the <c>str2</c> argument.</returns>
        /// <remarks>
        ///   <para>The outgoing message is a distribution matching the moments of <c>str2</c> as the random arguments are varied. The formula is <c>proj[p(str2) sum_(concat,str1) p(concat,str1) factor(concat,str1,str2)]/p(str2)</c>.</para>
        /// </remarks>
        public static StringDistribution Str2AverageConditional(StringDistribution concat, StringDistribution str1)
        {
            Argument.CheckIfNotNull(concat, "concat");
            Argument.CheckIfNotNull(str1, "str1");

            StringTransducer transducer = StringTransducer.Consume(str1.GetProbabilityFunction());

            transducer.AppendInPlace(StringTransducer.Copy());
            return(StringDistribution.FromWorkspace(transducer.ProjectSource(concat)));
        }
Ejemplo n.º 5
0
        /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="StringConcatOp"]/message_doc[@name="Str1AverageConditional(StringDistribution, StringDistribution)"]/*'/>
        public static StringDistribution Str1AverageConditional(StringDistribution concat, StringDistribution str2)
        {
            Argument.CheckIfNotNull(concat, "concat");
            Argument.CheckIfNotNull(str2, "str2");

            StringTransducer transducer = StringTransducer.Copy();

            transducer.AppendInPlace(StringTransducer.Consume(str2.ToAutomaton()));
            return(StringDistribution.FromWeightFunction(transducer.ProjectSource(concat.ToAutomaton())));
        }
Ejemplo n.º 6
0
        /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="StringConcatOp"]/message_doc[@name="Str1AverageConditional(StringDistribution, StringDistribution)"]/*'/>
        public static StringDistribution Str1AverageConditional(StringDistribution concat, StringDistribution str2)
        {
            Argument.CheckIfNotNull(concat, "concat");
            Argument.CheckIfNotNull(str2, "str2");

            StringTransducer transducer = StringTransducer.Copy();

            transducer.AppendInPlace(StringTransducer.Consume(str2.GetWorkspaceOrPoint()));
            return(StringDistribution.FromWorkspace(transducer.ProjectSource(concat.GetWorkspaceOrPoint())));
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Creates a transducer that replaces argument placeholders with the corresponding arguments.
        /// </summary>
        /// <param name="args">The list of arguments.</param>
        /// <param name="argNames">The list of argument names.</param>
        /// <param name="forBackwardMessage">Specifies whether the created transducer should be transposed so that the backward message can be computed.</param>
        /// <param name="withGroups">Specifies whether filled in arguments should be labeled with different groups.</param>
        /// <returns>The created transducer.</returns>
        private static StringTransducer GetPlaceholderReplacingTransducer(
            IList <StringAutomaton> args, IReadOnlyList <string> argNames, bool forBackwardMessage, bool withGroups)
        {
            var alternatives = new List <StringTransducer>();

            for (int argumentIndex = 0; argumentIndex < args.Count; ++argumentIndex)
            {
                StringTransducer alternative;
                if (!forBackwardMessage)
                {
                    alternative = StringTransducer.Consume(argNames[argumentIndex]);
                    alternative.AppendInPlace(StringTransducer.Produce(args[argumentIndex]), withGroups ? argumentIndex + 1 : 0);
                }
                else
                {
                    // After transposing 'Produce' will become 'Consume',
                    // and starting from 'Consume' makes projection computations more efficeint because it allows to detect dead braches earlier
                    Debug.Assert(!withGroups, "Groups are never needed for backward message.");
                    alternative = StringTransducer.Produce(args[argumentIndex]);
                    alternative.AppendInPlace(StringTransducer.Consume(argNames[argumentIndex]));
                }

                alternatives.Add(alternative);
            }

            StringTransducer result = DisallowBracesTransducer.Clone();

            result.AppendInPlace(StringTransducer.ConsumeElement('{'));
            result.AppendInPlace(StringTransducer.Sum(alternatives));
            result.AppendInPlace(StringTransducer.ConsumeElement('}'));
            result = StringTransducer.Repeat(result, minTimes: 0);
            result.AppendInPlace(DisallowBracesTransducer);

            if (forBackwardMessage)
            {
                result = StringTransducer.Transpose(result);
            }

            return(result);
        }
Ejemplo n.º 8
0
        public void CopySequence2()
        {
            const int CopyCount   = 10;
            const int LetterCount = 20;

            StringTransducer copy = StringTransducer.Copy();

            for (int i = 0; i < CopyCount - 1; ++i)
            {
                copy.AppendInPlace(StringTransducer.Copy());
            }

            var             sequence         = new string(Enumerable.Repeat('a', LetterCount).ToArray());
            StringAutomaton result           = copy.ProjectSource(sequence);
            var             expectedLogValue = Math.Log(StringInferenceTestUtilities.Partitions(LetterCount, CopyCount));

            Assert.Equal(expectedLogValue, result.GetLogValue(sequence), 1e-8);
        }