/**
         * Applies aggregation to two NLGElements e1 and e2, succeeding only if they
         * are clauses (that is, e1.getCategory() == e2.getCategory ==
         * {@link simplenlg.framework.PhraseCategory#CLAUSE}).
         */
        public override NLGElement apply(NLGElement previous, NLGElement next)
        {
            NLGElement aggregated = null;

            if (previous.Category == PhraseCategory.PhraseCategoryEnum.CLAUSE && next.Category == PhraseCategory.PhraseCategoryEnum.CLAUSE && PhraseChecker.nonePassive(previous, next) && !PhraseChecker.expletiveSubjects(previous, next))
            {
                if (PhraseChecker.sameSentences(previous, next))
                {                 // case 1: identical sentences: remove the current
                    aggregated = previous;
                }
                else if (PhraseChecker.sameFrontMods(previous, next) && PhraseChecker.sameSubjects(previous, next) && PhraseChecker.samePostMods(previous, next))
                {                 // case 2: subjects identical: coordinate VPs
                    aggregated = factory.createClause();
                    aggregated.setFeature(InternalFeature.SUBJECTS, previous.getFeatureAsElementList(InternalFeature.SUBJECTS));
                    aggregated.setFeature(InternalFeature.FRONT_MODIFIERS, previous.getFeatureAsElement(InternalFeature.FRONT_MODIFIERS));
                    aggregated.setFeature(Feature.CUE_PHRASE, previous.getFeatureAsElement(Feature.CUE_PHRASE));
                    aggregated.setFeature(InternalFeature.POSTMODIFIERS, previous.getFeatureAsElementList(InternalFeature.POSTMODIFIERS));
                    NLGElement vp;

                    if (!PhraseChecker.sameVPArgs(previous, next) && PhraseChecker.sameVPHead(previous, next) && PhraseChecker.sameVPModifiers(previous, next))
                    {                     // case 2.1: VPs have different arguments but same head & mods
                        NLGElement vp1 = previous.getFeatureAsElement(InternalFeature.VERB_PHRASE);
                        vp = factory.createVerbPhrase();
                        vp.setFeature(InternalFeature.HEAD, vp1.getFeatureAsElement(InternalFeature.HEAD));
                        vp.setFeature(InternalFeature.COMPLEMENTS, vp1.getFeatureAsElementList(InternalFeature.COMPLEMENTS));
                        vp.setFeature(InternalFeature.PREMODIFIERS, vp1.getFeatureAsElementList(InternalFeature.PREMODIFIERS));
                        vp.setFeature(InternalFeature.POSTMODIFIERS, vp1.getFeatureAsElementList(InternalFeature.POSTMODIFIERS));
                    }
                    else
                    {                     // case 2.2: just create a coordinate vP
                        NLGElement vp1 = previous.getFeatureAsElement(InternalFeature.VERB_PHRASE);
                        NLGElement vp2 = next.getFeatureAsElement(InternalFeature.VERB_PHRASE);
                        vp = factory.createCoordinatedPhrase(vp1, vp2);
                    }
                    // case 2.3: expletive subjects
                    aggregated.setFeature(InternalFeature.VERB_PHRASE, vp);
                }
                else if (PhraseChecker.sameFrontMods(previous, next) && PhraseChecker.sameVP(previous, next) && PhraseChecker.samePostMods(previous, next))
                {                 // case 3: identical VPs: conjoin subjects and front modifiers
                    aggregated = factory.createClause();
                    aggregated.setFeature(InternalFeature.FRONT_MODIFIERS, previous.getFeatureAsElementList(InternalFeature.FRONT_MODIFIERS));
                    CoordinatedPhraseElement subjects = factory.createCoordinatedPhrase();
                    subjects.Category = new PhraseCategory(PhraseCategory.PhraseCategoryEnum.NOUN_PHRASE);
                    IList <NLGElement> allSubjects = previous.getFeatureAsElementList(InternalFeature.SUBJECTS);
                    ((List <NLGElement>)allSubjects).AddRange(next.getFeatureAsElementList(InternalFeature.SUBJECTS));

                    foreach (NLGElement subj in allSubjects)
                    {
                        subjects.addCoordinate(subj);
                    }

                    aggregated.setFeature(InternalFeature.SUBJECTS, subjects);
                    aggregated.setFeature(InternalFeature.POSTMODIFIERS, previous.getFeatureAsElementList(InternalFeature.POSTMODIFIERS));
                    aggregated.setFeature(InternalFeature.VERB_PHRASE, previous.getFeature(InternalFeature.VERB_PHRASE));
                }
            }

            return(aggregated);
        }
Пример #2
0
        /**
         * Checks to see if the specifier can be raised and then raises it. In order
         * to be raised the specifier must be the same on all coordinates. For
         * example, <em>the cat and the dog</em> will be realised as
         * <em>the cat and dog</em> while <em>the cat and any dog</em> will remain
         * <em>the cat and any dog</em>.
         *
         * @param children
         *            the <code>List</code> of coordinates in the
         *            <code>CoordinatedPhraseElement</code>
         */
        private static void raiseSpecifier(IList <NLGElement> children)
        {
            bool       allMatch  = true;
            NLGElement child     = children[0];
            NLGElement specifier = null;
            string     test      = null;

            if (child != null)
            {
                specifier = child.getFeatureAsElement(InternalFeature.SPECIFIER);

                if (specifier != null)
                {
                    // AG: this assumes the specifier is an InflectedWordElement or
                    // phrase.
                    // it could be a Wordelement, in which case, we want the
                    // baseform
                    test = (specifier is WordElement) ? ((WordElement)specifier).BaseForm : specifier.getFeatureAsString(LexicalFeature.BASE_FORM);
                }

                if (!ReferenceEquals(test, null))
                {
                    int index = 1;

                    while (index < children.Count && allMatch)
                    {
                        child = children[index];

                        if (child == null)
                        {
                            allMatch = false;
                        }
                        else
                        {
                            specifier = child.getFeatureAsElement(InternalFeature.SPECIFIER);
                            string childForm = (specifier is WordElement) ? ((WordElement)specifier).BaseForm : specifier.getFeatureAsString(LexicalFeature.BASE_FORM);

                            if (!test.Equals(childForm))
                            {
                                allMatch = false;
                            }
                        }
                        index++;
                    }
                    if (allMatch)
                    {
                        for (int eachChild = 1; eachChild < children.Count; eachChild++)
                        {
                            child = children[eachChild];
                            child.setFeature(InternalFeature.RAISED, true);
                        }
                    }
                }
            }
        }
Пример #3
0
        /**
         * Check whether the phrases are lemma identical. This method returns
         * <code>true</code> in the following cases:
         *
         * <OL>
         * <LI>All phrases are {@link simplenlg.framework.NLGElement}s and they
         * have the same lexical head, irrespective of inflectional variations.</LI>
         * </OL>
         *
         * @return <code>true</code> if the pair is lemma identical
         */
        public virtual bool lemmaIdentical()
        {
            bool ident = phrases.Any();

            for (int i = 1; i < phrases.Count && ident; i++)
            {
                NLGElement left  = phrases[i - 1];
                NLGElement right = phrases[i];


                if (left != null && right != null)
                {
                    NLGElement leftHead  = left.getFeatureAsElement(InternalFeature.HEAD);
                    NLGElement rightHead = right.getFeatureAsElement(InternalFeature.HEAD);
                    ident = (leftHead == rightHead || leftHead.Equals(rightHead));
                }
            }

            return(ident);
        }
Пример #4
0
        /**
         * Check that a list of sentences have the same verb
         *
         * @param sentences
         *            the sentences
         * @return <code>true</code> if for every pair of sentences <code>s1</code>
         *         and <code>s2</code>
         *         <code>s1.getVerbPhrase().getHead().equals(s2.getVerbPhrase().getHead())</code>
         */
        public static bool sameVPHead(params NLGElement[] sentences)
        {
            bool equal = sentences.Length >= 2;

            for (int i = 1; i < sentences.Length && equal; i++)
            {
                NLGElement vp1 = sentences[i - 1].getFeatureAsElement(InternalFeature.VERB_PHRASE);
                NLGElement vp2 = sentences[i].getFeatureAsElement(InternalFeature.VERB_PHRASE);

                if (vp1 != null && vp2 != null)
                {
                    NLGElement h1 = vp1.getFeatureAsElement(InternalFeature.HEAD);
                    NLGElement h2 = vp2.getFeatureAsElement(InternalFeature.HEAD);
                    equal = h1 != null && h2 != null?h1.Equals(h2) : false;
                }
                else
                {
                    equal = false;
                }
            }

            return(equal);
        }
Пример #5
0
        /**
         * Checks the subjects of the phrase to determine if there is more than one
         * subject. This ensures that the verb phrase is correctly set. Also set
         * person correctly
         *
         * @param phrase
         *            the <code>PhraseElement</code> representing this clause.
         * @param verbElement
         *            the <code>NLGElement</code> representing the verb phrase for
         *            this clause.
         */
        private static void checkSubjectNumberPerson(PhraseElement phrase, NLGElement verbElement)
        {
            NLGElement         currentElement = null;
            IList <NLGElement> subjects       = phrase.getFeatureAsElementList(InternalFeature.SUBJECTS);
            bool   pluralSubjects             = false;
            Person?person = null;

            if (subjects != null)
            {
                switch (subjects.Count)
                {
                case 0:
                    break;

                case 1:
                    currentElement = subjects[0];
                    // coordinated NP with "and" are plural (not coordinated NP with "or")
                    if (currentElement is CoordinatedPhraseElement && ((CoordinatedPhraseElement)currentElement).checkIfPlural())
                    {
                        pluralSubjects = true;
                    }
                    else if (((NumberAgreement?)currentElement.getFeature(Feature.NUMBER) == NumberAgreement.PLURAL) && !(currentElement is SPhraseSpec))                     // ER mod-
                    {
                        // ER mod-clauses are singular as NPs, even if they are plural internally
                        pluralSubjects = true;
                    }
                    else if (currentElement.isA(new PhraseCategory(PhraseCategory.PhraseCategoryEnum.NOUN_PHRASE)))
                    {
                        NLGElement currentHead = currentElement.getFeatureAsElement(InternalFeature.HEAD);
                        person = (Person?)currentElement.getFeature(Feature.PERSON);

                        if (currentHead == null)
                        {
                            // subject is null and therefore is not gonna be plural
                            pluralSubjects = false;
                        }
                        else if ((NumberAgreement?)currentHead.getFeature(Feature.NUMBER) == NumberAgreement.PLURAL)
                        {
                            pluralSubjects = true;
                        }
                        else if (currentHead is ListElement)
                        {
                            pluralSubjects = true;

                            /*
                             * } else if (currentElement instanceof
                             * CoordinatedPhraseElement &&
                             * "and".equals(currentElement.getFeatureAsString(
                             * //$NON-NLS-1$ Feature.CONJUNCTION))) { pluralSubjects
                             * = true;
                             */
                        }
                    }
                    break;

                default:
                    pluralSubjects = true;
                    break;
                }
            }
            if (verbElement != null)
            {
                verbElement.setFeature(Feature.NUMBER, pluralSubjects ? NumberAgreement.PLURAL : (NumberAgreement?)phrase.getFeature(Feature.NUMBER));
                if (person != null)
                {
                    verbElement.setFeature(Feature.PERSON, person);
                }
            }
        }