Пример #1
0
        /// <summary>
        /// Returns the specified number of parses or fewer for the specified tokens.
        /// </summary>
        /// <param name="tokens">A parse containing the tokens with a single parent node.</param>
        /// <param name="numParses">The number of parses desired.</param>
        /// <returns>The specified number of parses for the specified tokens.</returns>
        /// <remarks>
        /// The nodes within the returned parses are shared with other parses and therefore their
        /// parent node references will not be consistent with their child node reference.
        /// <see cref="SharpNL.Parser.Parse.Parent"/> can be used to make the parents consistent with a
        /// particular parse, but subsequent calls to this property can invalidate the results of earlier
        /// calls.
        /// </remarks>
        public Parse[] Parse(Parse tokens, int numParses)
        {
            if (createDerivationString)
            {
                tokens.Derivation = new StringBuilder();
            }

            odh.Clear();
            ndh.Clear();
            completeParses.Clear();
            var derivationStage     = 0; //derivation length
            var maxDerivationLength = 2 * tokens.ChildCount + 3;

            odh.Add(tokens);
            Parse  guess        = null;
            double minComplete  = 2;
            double bestComplete = -100000; //approximating -infinity/0 in ln domain

            while (odh.Size() > 0 &&
                   (completeParses.Size() < M || odh.First().Probability < minComplete) &&
                   derivationStage < maxDerivationLength)
            {
                ndh = new ListHeap <Parse>(K);

                var derivationRank = 0;
                // foreach derivation
                for (var pi = odh.GetEnumerator(); pi.MoveNext() && derivationRank < K; derivationRank++)
                {
                    var tp = pi.Current;

                    //TODO: Need to look at this for K-best parsing cases

                    /*
                     * if (tp.getProb() < bestComplete) { //this parse and the ones which follow will never win, stop advancing.
                     * break;
                     * }
                     */

                    if (guess == null && derivationStage == 2)
                    {
                        guess = tp;
                    }
#if DEBUG
                    if (debugOn)
                    {
                        Console.Out.WriteLine(derivationStage + " " + derivationRank + " " + tp.Probability);
                        Console.Out.WriteLine(tp.ToString());
                        Console.Out.WriteLine();
                    }
#endif

                    Parse[] nd;

                    if (derivationStage == 0)
                    {
                        nd = AdvanceTags(tp);
                    }
                    else if (derivationStage == 1)
                    {
                        nd = AdvanceChunks(tp, ndh.Size() < K ? bestComplete : ndh.Last().Probability);
                    }
                    else
                    {
                        // i > 1
                        nd = AdvanceParses(tp, Q);
                    }

                    if (nd != null)
                    {
                        for (int k = 0, kl = nd.Length; k < kl; k++)
                        {
                            if (nd[k].Complete)
                            {
                                AdvanceTop(nd[k]);
                                if (nd[k].Probability > bestComplete)
                                {
                                    bestComplete = nd[k].Probability;
                                }
                                if (nd[k].Probability < minComplete)
                                {
                                    minComplete = nd[k].Probability;
                                }
                                completeParses.Add(nd[k]);
                            }
                            else
                            {
                                ndh.Add(nd[k]);
                            }
                        }
                    }
                    else
                    {
                        if (ReportFailedParse)
                        {
                            Console.Error.WriteLine("Couldn't advance parse " + derivationStage + " stage " +
                                                    derivationRank + "!\n");
                        }
                        AdvanceTop(tp);
                        completeParses.Add(tp);
                    }
                }
                derivationStage++;
                odh = ndh;
            }
            if (completeParses.Size() == 0)
            {
                if (ReportFailedParse)
                {
                    Console.Error.WriteLine("Couldn't find parse for: " + tokens);
                }
                //Parse r = (Parse) odh.first();
                //r.show();
                //System.out.println();
                return(new[] { guess });
            }
            if (numParses == 1)
            {
                return(new[] { completeParses.First() });
            }
            var topParses = new List <Parse>();
            while (!completeParses.IsEmpty() && topParses.Count < numParses)
            {
                var tp = completeParses.Extract();
                topParses.Add(tp);
                //parses.remove(tp);
            }
            return(topParses.ToArray());
        }