/** * Copies the front modifiers of the clause to the list of post-modifiers of * the verb only if the phrase has infinitive form. * * @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 copyFrontModifiers(PhraseElement phrase, INLGElement verbElement) { var frontModifiers = phrase.getFeatureAsElementList(InternalFeature.FRONT_MODIFIERS.ToString()); var clauseForm = phrase.getFeature(Feature.FORM.ToString()); // bug fix by Chris Howell (Agfa) -- do not overwrite existing post-mods // in the VP if (verbElement != null) { List <INLGElement> phrasePostModifiers = phrase.getFeatureAsElementList(InternalFeature.POSTMODIFIERS.ToString()); if (verbElement is PhraseElement) { List <INLGElement> verbPostModifiers = verbElement.getFeatureAsElementList(InternalFeature.POSTMODIFIERS.ToString()); foreach (var eachModifier in phrasePostModifiers) { // need to check that VP doesn't already contain the // post-modifier // this only happens if the phrase has already been realised // and later modified, with realiser called again. In that // case, postmods will be copied over twice if (!verbPostModifiers.Contains(eachModifier)) { ((PhraseElement)verbElement).addPostModifier(eachModifier); } } } } // if (verbElement != null) { // verbElement.setFeature(InternalFeature.POSTMODIFIERS, phrase // .getFeature(InternalFeature.POSTMODIFIERS)); // } if (Form.INFINITIVE.Equals(clauseForm)) { phrase.setFeature(Feature.SUPRESSED_COMPLEMENTISER.ToString(), true); foreach (var eachModifier in frontModifiers) { if (verbElement is PhraseElement) { ((PhraseElement)verbElement).addPostModifier(eachModifier); } } phrase.removeFeature(InternalFeature.FRONT_MODIFIERS.ToString()); if (verbElement != null) { verbElement.setFeature(InternalFeature.NON_MORPH.ToString(), true); } } }
/** * Realises the complements of the phrase adding <em>and</em> where * appropriate. * * @param parent * the parent <code>SyntaxProcessor</code> that will do the * realisation of the complementiser. * @param phrase * the <code>PhraseElement</code> representing this noun phrase. * @param realisedElement * the current realisation of the noun phrase. */ private static void realiseComplements(SyntaxProcessor parent, PhraseElement phrase, ListElement realisedElement) { var firstProcessed = false; INLGElement currentElement = null; foreach (INLGElement complement in phrase.getFeatureAsElementList(InternalFeature.COMPLEMENTS.ToString())) { currentElement = parent.realise(complement); if (currentElement != null) { currentElement.setFeature(InternalFeature.DISCOURSE_FUNCTION.ToString(), DiscourseFunction.COMPLEMENT); if (firstProcessed) { realisedElement.addComponent(new InflectedWordElement( "and", new LexicalCategory_CONJUNCTION())); } else { firstProcessed = true; } realisedElement.addComponent(currentElement); } } }
/** * Checks the discourse function of the clause and alters the form of the * clause as necessary. The following algorithm is used: <br> * * <pre> * If the clause represents a direct or indirect object then * If form is currently Imperative then * Set form to Infinitive * Suppress the complementiser * If form is currently Gerund and there are no subjects * Suppress the complementiser * If the clause represents a subject then * Set the form to be Gerund * Suppress the complementiser * </pre> * * @param phrase * the <code>PhraseElement</code> representing this clause. */ private static void checkDiscourseFunction(PhraseElement phrase) { List <INLGElement> subjects = phrase.getFeatureAsElementList(InternalFeature.SUBJECTS.ToString()); var clauseForm = phrase.getFeature(Feature.FORM.ToString()); var discourseValue = phrase.getFeature(InternalFeature.DISCOURSE_FUNCTION.ToString()); if (DiscourseFunction.OBJECT.Equals(discourseValue) || DiscourseFunction.INDIRECT_OBJECT.Equals(discourseValue)) { if (Form.IMPERATIVE.Equals(clauseForm)) { phrase.setFeature(Feature.SUPRESSED_COMPLEMENTISER.ToString(), true); phrase.setFeature(Feature.FORM.ToString(), Form.INFINITIVE.ToString()); } else if (Form.GERUND.Equals(clauseForm) && subjects.Count == 0) { phrase.setFeature(Feature.SUPRESSED_COMPLEMENTISER.ToString(), true); } } else if (DiscourseFunction.SUBJECT.Equals(discourseValue)) { phrase.setFeature(Feature.FORM.ToString(), Form.GERUND); phrase.setFeature(Feature.SUPRESSED_COMPLEMENTISER.ToString(), true); } }
/** * Realises the subjects of a passive clause. * * @param phrase * the <code>PhraseElement</code> representing this clause. * @param parent * the parent <code>SyntaxProcessor</code> that will do the * realisation of the complementiser. * @param realisedElement * the current realisation of the clause. * @param phraseFactory * the phrase factory to be used. */ private static void addPassiveSubjects(PhraseElement phrase, SyntaxProcessor parent, ListElement realisedElement, NLGFactory phraseFactory) { INLGElement currentElement = null; if (phrase.getFeatureAsBoolean(Feature.PASSIVE.ToString())) { var allSubjects = phrase.getFeatureAsElementList(InternalFeature.SUBJECTS.ToString()); if (allSubjects.size() > 0 || phrase.hasFeature(Feature.INTERROGATIVE_TYPE.ToString())) { realisedElement.addComponent(parent.realise(phraseFactory.createPrepositionPhrase("by"))); } foreach (var subject in allSubjects) { subject.setFeature(Feature.PASSIVE.ToString(), true); if (subject.isA(PhraseCategoryEnum.NOUN_PHRASE) || subject is CoordinatedPhraseElement) { currentElement = parent.realise(subject); if (currentElement != null) { currentElement.setFeature(InternalFeature.DISCOURSE_FUNCTION.ToString(), DiscourseFunction.SUBJECT); realisedElement.addComponent(currentElement); } } } } }
/** * The main method for realising noun phrases. * * @param parent * the <code>SyntaxProcessor</code> that called this method. * @param phrase * the <code>PhraseElement</code> to be realised. * @return the realised <code>NLGElement</code>. */ public static INLGElement realise(SyntaxProcessor parent, PhraseElement phrase) { ListElement realisedElement = null; if (phrase != null && !phrase.getFeatureAsBoolean(Feature.ELIDED.ToString())) { realisedElement = new ListElement(); if (phrase.getFeatureAsBoolean(Feature.PRONOMINAL.ToString())) { realisedElement.addComponent(createPronoun(parent, phrase)); } else { realiseSpecifier(phrase, parent, realisedElement); realisePreModifiers(phrase, parent, realisedElement); realiseHeadNoun(phrase, parent, realisedElement); PhraseHelper.realiseList(parent, realisedElement, phrase .getFeatureAsElementList(InternalFeature.COMPLEMENTS.ToString()), DiscourseFunction.COMPLEMENT); PhraseHelper.realiseList(parent, realisedElement, phrase .getPostModifiers(), DiscourseFunction.POST_MODIFIER); } } return(realisedElement); }
/** * Realises the complements of this phrase. * * @param parent * the parent <code>SyntaxProcessor</code> that will do the * realisation of the complementiser. * @param phrase * the <code>PhraseElement</code> representing this noun phrase. * @param realisedElement * the current realisation of the noun phrase. */ private static void realiseComplements(SyntaxProcessor parent, PhraseElement phrase, ListElement realisedElement) { var indirects = new ListElement(); var directs = new ListElement(); var unknowns = new ListElement(); foreach (INLGElement complement in phrase.getFeatureAsElementList(InternalFeature.COMPLEMENTS.ToString())) { var discourseValue = complement .getFeature(InternalFeature.DISCOURSE_FUNCTION.ToString()); var currentElement = parent.realise(complement); if (currentElement != null) { currentElement.setFeature(InternalFeature.DISCOURSE_FUNCTION.ToString(), DiscourseFunction.COMPLEMENT); if (DiscourseFunction.INDIRECT_OBJECT.Equals(discourseValue)) { indirects.addComponent(currentElement); } else if (DiscourseFunction.OBJECT.Equals(discourseValue)) { directs.addComponent(currentElement); } else { unknowns.addComponent(currentElement); } } } if (!InterrogativeTypeExtensions.isIndirectObject(phrase .getFeature(Feature.INTERROGATIVE_TYPE.ToString()))) { realisedElement.addComponents(indirects.getChildren()); } if (!phrase.getFeatureAsBoolean(Feature.PASSIVE.ToString())) { if (!InterrogativeTypeExtensions.isAndObject(phrase .getFeature(Feature.INTERROGATIVE_TYPE.ToString()))) { realisedElement.addComponents(directs.getChildren()); } realisedElement.addComponents(unknowns.getChildren()); } }
/** * Adds the front modifiers to the end of the clause when dealing with * interrogatives. * * @param phrase * the <code>PhraseElement</code> representing this clause. * @param parent * the parent <code>SyntaxProcessor</code> that will do the * realisation of the complementiser. * @param realisedElement * the current realisation of the clause. */ private static void addInterrogativeFrontModifiers(PhraseElement phrase, SyntaxProcessor parent, ListElement realisedElement) { INLGElement currentElement = null; if (phrase.hasFeature(Feature.INTERROGATIVE_TYPE.ToString())) { foreach (var subject in phrase.getFeatureAsElementList(InternalFeature.FRONT_MODIFIERS.ToString())) { currentElement = parent.realise(subject); if (currentElement != null) { currentElement.setFeature(InternalFeature.DISCOURSE_FUNCTION.ToString(), DiscourseFunction.FRONT_MODIFIER); realisedElement.addComponent(currentElement); } } } }
/** * Realises the subjects for the clause. * * @param phrase * the <code>PhraseElement</code> representing this clause. * @param parent * the parent <code>SyntaxProcessor</code> that will do the * realisation of the complementiser. * @param realisedElement * the current realisation of the clause. */ private static ListElement realiseSubjects(PhraseElement phrase, SyntaxProcessor parent) { INLGElement currentElement = null; var realisedElement = new ListElement(); foreach (INLGElement subject in phrase.getFeatureAsElementList(InternalFeature.SUBJECTS.ToString())) { subject.setFeature(InternalFeature.DISCOURSE_FUNCTION.ToString(), DiscourseFunction.SUBJECT); if (Form.GERUND.Equals(phrase.getFeature(Feature.FORM.ToString())) && !phrase.getFeatureAsBoolean(Feature.SUPPRESS_GENITIVE_IN_GERUND.ToString())) { subject.setFeature(Feature.POSSESSIVE.ToString(), true); } currentElement = parent.realise(subject); if (currentElement != null) { realisedElement.addComponent(currentElement); } } return(realisedElement); }
/** * Determines the number agreement for the phrase ensuring that any number * agreement on the parent element is inherited by the phrase. * * @param parent * the parent element of the phrase. * @param phrase * the <code>PhraseElement</code> representing this noun phrase. * @return the <code>NumberAgreement</code> to be used for the phrase. */ private static NumberAgreement determineNumber(INLGElement parent, PhraseElement phrase) { var numberValue = phrase.getFeature(Feature.NUMBER.ToString()); NumberAgreement number; if (numberValue != null && numberValue is NumberAgreement) { number = (NumberAgreement)numberValue; } else { number = NumberAgreement.SINGULAR; } // Ehud Reiter = modified below to force number from VP for WHAT_SUBJECT // and WHO_SUBJECT interrogatuves if (parent is PhraseElement) { if (parent.isA(PhraseCategoryEnum.CLAUSE) && (PhraseHelper.isExpletiveSubject((PhraseElement)parent) || InterrogativeType.WHO_SUBJECT.Equals(parent .getFeature(Feature.INTERROGATIVE_TYPE.ToString())) || InterrogativeType.WHAT_SUBJECT .Equals(parent .getFeature(Feature.INTERROGATIVE_TYPE.ToString()))) && isCopular(phrase.getHead())) { if (hasPluralComplement(phrase .getFeatureAsElementList(InternalFeature.COMPLEMENTS.ToString()))) { number = NumberAgreement.PLURAL; } else { number = NumberAgreement.SINGULAR; } } } return(number); }
/** * Determines if the given phrase has an expletive as a subject. * * @param phrase * the <code>PhraseElement</code> to be examined. * @return <code>true</code> if the phrase has an expletive subject. */ public static bool isExpletiveSubject(PhraseElement phrase) { List <INLGElement> subjects = phrase .getFeatureAsElementList(InternalFeature.SUBJECTS.ToString()); var expletive = false; if (subjects.size() == 1) { var subjectNP = subjects.get(0); if (subjectNP.isA(PhraseCategoryEnum.NOUN_PHRASE)) { expletive = subjectNP.getFeatureAsBoolean( LexicalFeature.EXPLETIVE_SUBJECT); } else if (subjectNP.isA(PhraseCategoryEnum.CANNED_TEXT)) { expletive = "there".equalsIgnoreCase(subjectNP.getRealisation()); } } return(expletive); }
/** * 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, INLGElement verbElement) { INLGElement currentElement = null; List <INLGElement> subjects = phrase.getFeatureAsElementList(InternalFeature.SUBJECTS.ToString()); var pluralSubjects = false; var person = Person.FIRST; var personSet = false; if (subjects != null) { switch (subjects.size()) { case 0: break; case 1: currentElement = subjects.get(0); // coordinated NP with "and" are plural (not coordinated NP with // "or") if (currentElement is CoordinatedPhraseElement && ((CoordinatedPhraseElement)currentElement).checkIfPlural()) { pluralSubjects = true; } else if ((currentElement.getFeature(Feature.NUMBER.ToString())?.ToString() == NumberAgreement.PLURAL.ToString()) && !(currentElement is SPhraseSpec)) // ER mod- // clauses // are // singular // as // NPs, // even // if // they // are // plural // internally { pluralSubjects = true; } else if (currentElement.isA(PhraseCategoryEnum.NOUN_PHRASE)) { INLGElement currentHead = currentElement.getFeatureAsElement(InternalFeature.HEAD.ToString()); var p = currentElement.getFeature(Feature.PERSON.ToString()); if (p != null) { personSet = true; person = p.ToPerson(); } if (currentHead == null) { // subject is null and therefore is not gonna be plural pluralSubjects = false; } else if (currentHead.getFeature(Feature.NUMBER.ToString()) == NumberAgreement.PLURAL.ToString()) { pluralSubjects = true; } else if (currentHead is ListElement) { pluralSubjects = true; /* * } else if (currentElement is * CoordinatedPhraseElement && * "and".Equals(currentElement.getFeatureAsString( * Feature.CONJUNCTION))) { pluralSubjects * = true; */ } } break; default: pluralSubjects = true; break; } } if (verbElement != null) { verbElement.setFeature(Feature.NUMBER.ToString(), pluralSubjects ? NumberAgreement.PLURAL : phrase.getFeature(Feature.NUMBER.ToString())); if (personSet) { verbElement.setFeature(Feature.PERSON.ToString(), person); } } }
/** * The main method for controlling the syntax realisation of clauses. * * @param parent * the parent <code>SyntaxProcessor</code> that called this * method. * @param phrase * the <code>PhraseElement</code> representation of the clause. * @return the <code>NLGElement</code> representing the realised clause. */ public static INLGElement realise(SyntaxProcessor parent, PhraseElement phrase) { ListElement realisedElement = null; var phraseFactory = phrase.getFactory(); INLGElement splitVerb = null; var interrogObj = false; if (phrase != null) { realisedElement = new ListElement(); var verbElement = phrase.getFeatureAsElement(InternalFeature.VERB_PHRASE.ToString()); if (verbElement == null) { verbElement = phrase.getHead(); } checkSubjectNumberPerson(phrase, verbElement); checkDiscourseFunction(phrase); copyFrontModifiers(phrase, verbElement); addComplementiser(phrase, parent, realisedElement); addCuePhrase(phrase, parent, realisedElement); if (phrase.hasFeature(Feature.INTERROGATIVE_TYPE.ToString())) { var inter = phrase.getFeature(Feature.INTERROGATIVE_TYPE.ToString()); interrogObj = (InterrogativeType.WHAT_OBJECT.Equals(inter) || InterrogativeType.WHO_OBJECT.Equals(inter) || InterrogativeType.HOW_PREDICATE.Equals(inter) || InterrogativeType.HOW.Equals(inter) || InterrogativeType.WHY.Equals(inter) || InterrogativeType.WHERE.Equals(inter)); splitVerb = realiseInterrogative(phrase, parent, realisedElement, phraseFactory, verbElement); } else { PhraseHelper.realiseList(parent, realisedElement, phrase.getFeatureAsElementList(InternalFeature.FRONT_MODIFIERS.ToString()), DiscourseFunction.FRONT_MODIFIER); } addSubjectsToFront(phrase, parent, realisedElement, splitVerb); var passiveSplitVerb = addPassiveComplementsNumberPerson(phrase, parent, realisedElement, verbElement); if (passiveSplitVerb != null) { splitVerb = passiveSplitVerb; } // realise verb needs to know if clause is object interrogative realiseVerb(phrase, parent, realisedElement, splitVerb, verbElement, interrogObj); addPassiveSubjects(phrase, parent, realisedElement, phraseFactory); addInterrogativeFrontModifiers(phrase, parent, realisedElement); addEndingTo(phrase, parent, realisedElement, phraseFactory); } return(realisedElement); }