/** * 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); }
/** * 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); } } } } }
/** * 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); }
/** * 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); }
/** * 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); } } }