/**
   * This method performs the morphology for pronouns.
   *
   * @param element the <code>InflectedWordElement</code>.
   * @return a <code>StringElement</code> representing the word after inflection.
   */
  public NLGElement doPronounMorphology(InflectedWordElement element) {
    String realised = null;

    if (!element.getFeatureAsBoolean(InternalFeature.NON_MORPH).booleanValue()) {
      Object genderValue = element.getFeature(LexicalFeature.GENDER);
      Object personValue = element.getFeature(Feature.PERSON);

      // way of getting discourseValue changed by vaudrypl
      NLGElement parent = element.getParent();
      Object discourseValue = element.getFeature(InternalFeature.DISCOURSE_FUNCTION);
      if (discourseValue == DiscourseFunction.SUBJECT
          && parent != null
          && parent.isA(PhraseCategory.NOUN_PHRASE)) {
        discourseValue = parent.getFeature(InternalFeature.DISCOURSE_FUNCTION);
      }
      if (!(discourseValue instanceof DiscourseFunction))
        discourseValue = DiscourseFunction.SUBJECT;

      int numberIndex = element.isPlural() ? 1 : 0;
      int genderIndex = (genderValue instanceof Gender) ? ((Gender) genderValue).ordinal() : 2;

      int personIndex = (personValue instanceof Person) ? ((Person) personValue).ordinal() : 2;

      if (personIndex == 2) {
        personIndex += genderIndex;
      }

      int positionIndex = 0;

      if (element.getFeatureAsBoolean(LexicalFeature.REFLEXIVE).booleanValue()) {
        positionIndex = 2;
      } else if (element.getFeatureAsBoolean(Feature.POSSESSIVE).booleanValue()) {
        positionIndex = 3;
        if (DiscourseFunction.SPECIFIER.equals(discourseValue)) {
          positionIndex++;
        }
      } else {
        positionIndex =
            (DiscourseFunction.SUBJECT.equals(discourseValue)
                        && !element.getFeatureAsBoolean(Feature.PASSIVE).booleanValue())
                    || (DiscourseFunction.OBJECT.equals(discourseValue)
                        && element.getFeatureAsBoolean(Feature.PASSIVE).booleanValue())
                    || DiscourseFunction.SPECIFIER.equals(discourseValue)
                    || (DiscourseFunction.COMPLEMENT.equals(discourseValue)
                        && element.getFeatureAsBoolean(Feature.PASSIVE).booleanValue())
                ? 0
                : 1;
      }
      realised = PRONOUNS[numberIndex][positionIndex][personIndex];
    } else {
      realised = element.getBaseForm();
    }
    // vaudrypl added element as 2nd argument
    StringElement realisedElement = new StringElement(realised, element);
    realisedElement.setFeature(
        InternalFeature.DISCOURSE_FUNCTION, element.getFeature(InternalFeature.DISCOURSE_FUNCTION));

    return realisedElement;
  }
  /**
   * Convenience class to realise any NLGElement as a sentence
   *
   * @param element
   * @return String realisation of the NLGElement
   */
  public String realiseSentence(NLGElement element) {
    NLGElement realised = null;
    if (element instanceof DocumentElement) realised = realise(element);
    else {
      DocumentElement sentence = new DocumentElement(DocumentCategory.SENTENCE, null);
      sentence.addComponent(element);
      realised = realise(sentence);
    }

    if (realised == null) return null;
    else return realised.getRealisation();
  }
  /*
   * TODO: Let's go to sleep. reflexive verbs -- use of reflexive verb +
   * future proche
   */
  public void _test_lets_go_to_sleep() {
    ArrayList<PicWordAction> phrases = new ArrayList<PicWordAction>();
    phrases.add(new PicWordAction("on", Pic2NLG.ActionType.NOUN));

    NLGElement se_coucher = Pic2NLG.factory.createNLGElement("coucher");
    se_coucher.setFeature(LexicalFeature.REFLEXIVE, true);

    phrases.add(new PicWordAction(se_coucher, Pic2NLG.ActionType.VERB));
    phrases.add(new PicWordAction("futur_proche", Pic2NLG.ActionType.TENSE_PRESENT));

    assertEquals("On va se coucher", converter.convertPhrasesToNLG(phrases));
  }
  /**
   * This is the main method for performing the morphology. It effectively
   * examines the lexical category of the element and calls the relevant set
   * of rules from <code>MorphologyRules</em>.
   *
   * @param element
   *            the <code>InflectedWordElement</code>
   * @return an <code>NLGElement</code> reflecting the correct inflection for
   *         the word.
   *
   */
  private NLGElement doMorphology(InflectedWordElement element) {
    NLGElement realisedElement = null;
    if (element.getFeatureAsBoolean(InternalFeature.NON_MORPH).booleanValue()) {
      realisedElement = new StringElement(element.getBaseForm());
      realisedElement.setFeature(
          InternalFeature.DISCOURSE_FUNCTION,
          element.getFeature(InternalFeature.DISCOURSE_FUNCTION));
    } else {
      NLGElement baseWord = element.getFeatureAsElement(InternalFeature.BASE_WORD);

      if (baseWord == null && this.lexicon != null) {
        baseWord = this.lexicon.lookupWord(element.getBaseForm());
      }
      ElementCategory category = element.getCategory();
      if (category instanceof LexicalCategory) {
        switch ((LexicalCategory) category) {
          case PRONOUN:
            realisedElement = MorphologyRules.doPronounMorphology(element);
            break;

          case NOUN:
            realisedElement = MorphologyRules.doNounMorphology(element, (WordElement) baseWord);
            break;

          case VERB:
            realisedElement = MorphologyRules.doVerbMorphology(element, (WordElement) baseWord);
            break;

          case ADJECTIVE:
            realisedElement =
                MorphologyRules.doAdjectiveMorphology(element, (WordElement) baseWord);
            break;

          case ADVERB:
            realisedElement = MorphologyRules.doAdverbMorphology(element, (WordElement) baseWord);
            break;

          default:
            realisedElement = new StringElement(element.getBaseForm());
            realisedElement.setFeature(
                InternalFeature.DISCOURSE_FUNCTION,
                element.getFeature(InternalFeature.DISCOURSE_FUNCTION));
        }
      }
    }
    return realisedElement;
  }
  /**
   * Determines the maximim position at which this modifier can occur.
   *
   * @param modifier the modifier to be checked.
   * @return the maximum position for this modifier.
   */
  private static int getMaxPos(NLGElement modifier) {
    int position = NOUN_POSITION;

    if (modifier.isA(LexicalCategory.ADJECTIVE) || modifier.isA(PhraseCategory.ADJECTIVE_PHRASE)) {
      WordElement adjective = getHeadWordElement(modifier);

      if (adjective.getFeatureAsBoolean(LexicalFeature.CLASSIFYING).booleanValue()) {
        position = CLASSIFYING_POSITION;
      } else if (adjective.getFeatureAsBoolean(LexicalFeature.COLOUR).booleanValue()) {
        position = COLOUR_POSITION;
      } else if (adjective.getFeatureAsBoolean(LexicalFeature.QUALITATIVE).booleanValue()) {
        position = QUALITATIVE_POSITION;
      } else {
        position = CLASSIFYING_POSITION;
      }
    }
    return position;
  }
  /** Test the genders of multi-gender words, like chanteuse */
  public void _test_je_veux_etre_chanteuse_gender() {
    ArrayList<PicWordAction> phrases = new ArrayList<PicWordAction>();
    // je avoir [past] assez bonbon [plural] ==> j'ai eu assez des bonbons
    phrases.add(new PicWordAction("je", Pic2NLG.ActionType.NOUN));
    phrases.add(new PicWordAction("vouloir", Pic2NLG.ActionType.VERB));

    // phrases.add(new PicWordAction("past", Pic2NLG.wordTYPE.TENSE));
    phrases.add(new PicWordAction("etre", Pic2NLG.ActionType.VERB));

    NLGElement chanteuse = Pic2NLG.factory.createNounPhrase("un", "chanteur");
    chanteuse.setFeature(LexicalFeature.GENDER, Gender.FEMININE);

    System.out.println(chanteuse);
    phrases.add(new PicWordAction(chanteuse, Pic2NLG.ActionType.NOUN));

    // TODO: phrases.add(new PicWordAction("plural",
    // Pic2NLG.ActionType.NUMBER_AGREEMENT));
    assertEquals("Je veux etre une chanteuse", converter.convertPhrasesToNLG(phrases));
  }
  @Override
  public SPhraseSpec generate() {
    Lexicon lexicon = Lexicon.getDefaultLexicon();
    NLGFactory nlgFactory = new NLGFactory(lexicon);

    SPhraseSpec s = nlgFactory.createClause();

    s.setFrontModifier("moreover");

    NPPhraseSpec secondDive = nlgFactory.createNounPhrase("dive");
    secondDive.setDeterminer("your");
    secondDive.setPreModifier("second");

    VPPhraseSpec be = nlgFactory.createVerbPhrase("be");
    NLGElement predicative = nlgFactory.createInflectedWord("deep", LexicalCategory.ADVERB);
    predicative.setFeature(Feature.IS_COMPARATIVE, true);
    be.addComplement(predicative);

    PPPhraseSpec than = nlgFactory.createPrepositionPhrase("than");
    NPPhraseSpec firstDive = nlgFactory.createNounPhrase("one");
    firstDive.setDeterminer("the");
    firstDive.setPreModifier("first");
    than.addComplement(firstDive);

    s.setSubject(secondDive);
    s.setVerb(be);
    s.addComplement(than);
    s.setFeature(Feature.TENSE, Tense.PAST);

    SPhraseSpec which = nlgFactory.createClause();
    VPPhraseSpec beNot = nlgFactory.createVerbPhrase("be");
    beNot.setFeature(Feature.NEGATED, true);

    NLGElement recommended = nlgFactory.createAdjectivePhrase("recommended");
    beNot.addComplement(recommended);
    beNot.addModifier("really");
    which.setVerb(beNot);

    which.setFeature(Feature.COMPLEMENTISER, "which");
    s.addComplement(which);

    return s;
  }
  /**
   * Realises the specifier of the noun phrase.
   *
   * @param phrase the <code>PhraseElement</code> representing this noun phrase.
   * @param parent the parent <code>SyntaxProcessor</code> that will do the realisation of the
   *     complementiser.
   * @param realisedElement the current realisation of the noun phrase.
   */
  private static void realiseSpecifier(
      PhraseElement phrase, SyntaxProcessor parent, ListElement realisedElement) {
    NLGElement specifierElement = phrase.getFeatureAsElement(InternalFeature.SPECIFIER);

    if (specifierElement != null
        && !phrase.getFeatureAsBoolean(InternalFeature.RAISED).booleanValue()
        && !phrase.getFeatureAsBoolean(Feature.ELIDED).booleanValue()) {

      if (!specifierElement.isA(LexicalCategory.PRONOUN)) {
        specifierElement.setFeature(Feature.NUMBER, phrase.getFeature(Feature.NUMBER));
      }

      NLGElement currentElement = parent.realise(specifierElement);

      if (currentElement != null) {
        currentElement.setFeature(InternalFeature.DISCOURSE_FUNCTION, DiscourseFunction.SPECIFIER);
        realisedElement.addComponent(currentElement);
      }
    }
  }
  /**
   * Realises the head noun of the noun phrase.
   *
   * @param phrase the <code>PhraseElement</code> representing this noun phrase.
   * @param parent the parent <code>SyntaxProcessor</code> that will do the realisation of the
   *     complementiser.
   * @param realisedElement the current realisation of the noun phrase.
   */
  private static void realiseHeadNoun(
      PhraseElement phrase, SyntaxProcessor parent, ListElement realisedElement) {
    NLGElement headElement = phrase.getHead();

    if (headElement != null) {
      headElement.setFeature(Feature.ELIDED, phrase.getFeature(Feature.ELIDED));
      headElement.setFeature(LexicalFeature.GENDER, phrase.getFeature(LexicalFeature.GENDER));
      headElement.setFeature(InternalFeature.ACRONYM, phrase.getFeature(InternalFeature.ACRONYM));
      headElement.setFeature(Feature.NUMBER, phrase.getFeature(Feature.NUMBER));
      headElement.setFeature(Feature.PERSON, phrase.getFeature(Feature.PERSON));
      headElement.setFeature(Feature.POSSESSIVE, phrase.getFeature(Feature.POSSESSIVE));
      headElement.setFeature(Feature.PASSIVE, phrase.getFeature(Feature.PASSIVE));
      NLGElement currentElement = parent.realise(headElement);
      currentElement.setFeature(InternalFeature.DISCOURSE_FUNCTION, DiscourseFunction.SUBJECT);
      realisedElement.addComponent(currentElement);
    }
  }
  /**
   * Retrieves the correct representation of the word from the element. This method will find the
   * <code>WordElement</code>, if it exists, for the given phrase or inflected word.
   *
   * @param element the <code>NLGElement</code> from which the head is required.
   * @return the <code>WordElement</code>
   */
  private static WordElement getHeadWordElement(NLGElement element) {
    WordElement head = null;

    if (element instanceof WordElement) head = (WordElement) element;
    else if (element instanceof InflectedWordElement) {
      head = (WordElement) element.getFeature(InternalFeature.BASE_WORD);
    } else if (element instanceof PhraseElement) {
      head = getHeadWordElement(((PhraseElement) element).getHead());
    }

    return head;
  }
  @Override
  public NLGElement realise(NLGElement element) {
    NLGElement realisedElement = null;
    if (element instanceof InflectedWordElement) {
      realisedElement = doMorphology((InflectedWordElement) element);
    } else if (element instanceof StringElement) {
      realisedElement = element;
    } else if (element instanceof WordElement) {
      // AG: now retrieves the default spelling variant, not the baseform
      // String baseForm = ((WordElement) element).getBaseForm();
      String defaultSpell = ((WordElement) element).getDefaultSpellingVariant();

      if (defaultSpell != null) {
        realisedElement = new StringElement(defaultSpell);
      }
    } else if (element instanceof DocumentElement) {
      List<NLGElement> children = element.getChildren();
      ((DocumentElement) element).setComponents(realise(children));
      realisedElement = element;
    } else if (element instanceof ListElement) {
      realisedElement = new ListElement();
      ((ListElement) realisedElement).addComponents(realise(element.getChildren()));
    } else if (element instanceof CoordinatedPhraseElement) {
      List<NLGElement> children = element.getChildren();
      ((CoordinatedPhraseElement) element).clearCoordinates();

      if (children != null && children.size() > 0) {
        ((CoordinatedPhraseElement) element).addCoordinate(realise(children.get(0)));
        for (int index = 1; index < children.size(); index++) {
          ((CoordinatedPhraseElement) element).addCoordinate(realise(children.get(index)));
        }
        realisedElement = element;
      }
    } else if (element != null) {
      realisedElement = element;
    }
    return realisedElement;
  }
  @Override
  public List<NLGElement> realise(List<NLGElement> elements) {
    List<NLGElement> realisedElements = new ArrayList<NLGElement>();
    NLGElement currentElement = null;
    NLGElement determiner = null;

    if (elements != null) {
      for (NLGElement eachElement : elements) {
        currentElement = realise(eachElement);
        if (currentElement != null) {
          realisedElements.add(realise(currentElement));
          if (determiner == null
              && DiscourseFunction.SPECIFIER.equals(
                  currentElement.getFeature(InternalFeature.DISCOURSE_FUNCTION))) {
            determiner = currentElement;
            determiner.setFeature(Feature.NUMBER, eachElement.getFeature(Feature.NUMBER));
            // MorphologyRules.doDeterminerMorphology(determiner,
            // currentElement.getRealisation());
          } else if (determiner != null) {

            if (currentElement instanceof ListElement) {
              NLGElement firstChild = ((ListElement) currentElement).getChildren().get(0);

              if (firstChild != null) {
                MorphologyRules.doDeterminerMorphology(determiner, firstChild.getRealisation());
              }
            } else {
              MorphologyRules.doDeterminerMorphology(determiner, currentElement.getRealisation());
            }

            determiner = null;
          }
        }
      }
    }
    return realisedElements;
  }
  /**
   * Creates the appropriate pronoun if the subject of the noun phrase is pronominal.
   *
   * @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.
   * @return the <code>NLGElement</code> representing the pronominal.
   */
  private static NLGElement createPronoun(SyntaxProcessor parent, PhraseElement phrase) {

    String pronoun = "it"; // $NON-NLS-1$
    NLGFactory phraseFactory = phrase.getFactory();
    Object personValue = phrase.getFeature(Feature.PERSON);

    if (Person.FIRST.equals(personValue)) {
      pronoun = "I"; // $NON-NLS-1$
    } else if (Person.SECOND.equals(personValue)) {
      pronoun = "you"; // $NON-NLS-1$
    } else {
      Object genderValue = phrase.getFeature(LexicalFeature.GENDER);
      if (Gender.FEMININE.equals(genderValue)) {
        pronoun = "she"; // $NON-NLS-1$
      } else if (Gender.MASCULINE.equals(genderValue)) {
        pronoun = "he"; // $NON-NLS-1$
      }
    }
    // AG: createWord now returns WordElement; so we embed it in an
    // inflected word element here
    NLGElement element;
    NLGElement proElement = phraseFactory.createWord(pronoun, LexicalCategory.PRONOUN);

    if (proElement instanceof WordElement) {
      element = new InflectedWordElement((WordElement) proElement);
      element.setFeature(
          LexicalFeature.GENDER, ((WordElement) proElement).getFeature(LexicalFeature.GENDER));
      // Ehud - also copy over person
      element.setFeature(Feature.PERSON, ((WordElement) proElement).getFeature(Feature.PERSON));
    } else {
      element = proElement;
    }

    element.setFeature(InternalFeature.DISCOURSE_FUNCTION, DiscourseFunction.SPECIFIER);
    element.setFeature(Feature.POSSESSIVE, phrase.getFeature(Feature.POSSESSIVE));
    element.setFeature(Feature.NUMBER, phrase.getFeature(Feature.NUMBER));

    if (phrase.hasFeature(InternalFeature.DISCOURSE_FUNCTION)) {
      element.setFeature(
          InternalFeature.DISCOURSE_FUNCTION,
          phrase.getFeature(InternalFeature.DISCOURSE_FUNCTION));
    }

    return element;
  }
Exemple #14
0
  @Override
  public NLGElement realise(NLGElement element) {

    StringBuilder debug = new StringBuilder();

    if (this.debug) {
      System.out.println("INITIAL TREE\n"); // $NON-NLS-1$
      System.out.println(element.printTree(null));
      debug.append("INITIAL TREE<br/>");
      debug.append(element.printTree("&nbsp;&nbsp;").replaceAll("\n", "<br/>"));
    }

    NLGElement postSyntax = this.syntax.realise(element);
    if (this.debug) {
      System.out.println("<br/>POST-SYNTAX TREE<br/>"); // $NON-NLS-1$
      System.out.println(postSyntax.printTree(null));
      debug.append("<br/>POST-SYNTAX TREE<br/>");
      debug.append(postSyntax.printTree("&nbsp;&nbsp;").replaceAll("\n", "<br/>"));
    }

    NLGElement postMorphology = this.morphology.realise(postSyntax);
    if (this.debug) {
      System.out.println("\nPOST-MORPHOLOGY TREE\n"); // $NON-NLS-1$
      System.out.println(postMorphology.printTree(null));
      debug.append("<br/>POST-MORPHOLOGY TREE<br/>");
      debug.append(postMorphology.printTree("&nbsp;&nbsp;").replaceAll("\n", "<br/>"));
    }

    NLGElement postOrthography = this.orthography.realise(postMorphology);
    if (this.debug) {
      System.out.println("\nPOST-ORTHOGRAPHY TREE\n"); // $NON-NLS-1$
      System.out.println(postOrthography.printTree(null));
      debug.append("<br/>POST-ORTHOGRAPHY TREE<br/>");
      debug.append(postOrthography.printTree("&nbsp;&nbsp;").replaceAll("\n", "<br/>"));
    }

    NLGElement postFormatter = null;
    if (this.formatter != null) {
      postFormatter = this.formatter.realise(postOrthography);
      if (this.debug) {
        System.out.println("\nPOST-FORMATTER TREE\n"); // $NON-NLS-1$
        System.out.println(postFormatter.printTree(null));
        debug.append("<br/>POST-FORMATTER TREE<br/>");
        debug.append(postFormatter.printTree("&nbsp;&nbsp;").replaceAll("\n", "<br/>"));
      }

    } else {
      postFormatter = postOrthography;
    }

    if (this.debug) {
      postFormatter.setFeature("debug", debug.toString());
    }

    return postFormatter;
  }
  @Override
  public NLGElement realise(NLGElement element) {
    NLGElement realisedElement = null;

    if (element != null && !element.getFeatureAsBoolean(Feature.ELIDED).booleanValue()) {

      if (element instanceof DocumentElement) {
        List<NLGElement> children = element.getChildren();
        ((DocumentElement) element).setComponents(realise(children));
        realisedElement = element;

      } else if (element instanceof PhraseElement) {
        realisedElement = realisePhraseElement((PhraseElement) element);

      } else if (element instanceof ListElement) {
        realisedElement = new ListElement();
        ((ListElement) realisedElement).addComponents(realise(element.getChildren()));

      } else if (element instanceof InflectedWordElement) {
        String baseForm = ((InflectedWordElement) element).getBaseForm();
        ElementCategory category = element.getCategory();

        if (this.lexicon != null && baseForm != null) {
          WordElement word = ((InflectedWordElement) element).getBaseWord();

          if (word == null) {
            if (category instanceof LexicalCategory) {
              word = this.lexicon.lookupWord(baseForm, (LexicalCategory) category);
            } else {
              word = this.lexicon.lookupWord(baseForm);
            }
          }

          if (word != null) {
            ((InflectedWordElement) element).setBaseWord(word);
          }
        }

        realisedElement = element;

      } else if (element instanceof WordElement) {
        // AG: need to check if it's a word element, in which case it
        // needs to be marked for inflection
        InflectedWordElement infl = new InflectedWordElement((WordElement) element);

        // the inflected word inherits all features from the base word
        for (String feature : element.getAllFeatureNames()) {
          infl.setFeature(feature, element.getFeature(feature));
        }

        realisedElement = realise(infl);

      } else if (element instanceof CoordinatedPhraseElement) {
        realisedElement = CoordinatedPhraseHelper.realise(this, (CoordinatedPhraseElement) element);

      } else {
        realisedElement = element;
      }
    }

    // Remove the spurious ListElements that have only one element.
    if (realisedElement instanceof ListElement) {
      if (((ListElement) realisedElement).size() == 1) {
        realisedElement = ((ListElement) realisedElement).getFirst();
      }
    }
    return realisedElement;
  }