예제 #1
0
 private NLGElement getNLFromExpressions(List<Expr> expressions) {
   List<NLGElement> nlgs = new ArrayList<NLGElement>();
   NLGElement elt;
   for (Expr e : expressions) {
     elt = getNLFromSingleExpression(e);
     if (elt != null) {
       nlgs.add(elt);
     }
   }
   // now process
   if (nlgs.isEmpty()) {
     return null;
   }
   if (nlgs.size() == 1) {
     return nlgs.get(0);
   } else {
     CoordinatedPhraseElement cpe;
     cpe = nlgFactory.createCoordinatedPhrase(nlgs.get(0), nlgs.get(1));
     for (int i = 2; i < nlgs.size(); i++) {
       cpe.addComplement(nlgs.get(i));
     }
     cpe.setConjunction("and");
     return cpe;
   }
 }
예제 #2
0
 public NLGElement getNLForTripleList(List<Triple> triples, String conjunction) {
   if (triples.isEmpty()) {
     return null;
   }
   if (triples.size() == 1) {
     return getNLForTriple(triples.get(0));
   } else {
     CoordinatedPhraseElement cpe;
     Triple t0 = triples.get(0);
     Triple t1 = triples.get(1);
     cpe = nlgFactory.createCoordinatedPhrase(getNLForTriple(t0), getNLForTriple(t1));
     for (int i = 2; i < triples.size(); i++) {
       cpe.addCoordinate(getNLForTriple(triples.get(i)));
     }
     cpe.setConjunction(conjunction);
     return cpe;
   }
 }
예제 #3
0
  /**
   * Processes a list of elements. These can be elements of the where clause or of an optional
   * clause
   *
   * @param e List of query elements
   * @return Conjunctive natural representation of the list of elements.
   */
  public NLGElement getNLFromElements(List<Element> e) {
    if (e.isEmpty()) {
      return null;
    }
    if (e.size() == 1) {
      return getNLFromSingleClause(e.get(0));
    } else {
      CoordinatedPhraseElement cpe;
      cpe =
          nlgFactory.createCoordinatedPhrase(
              getNLFromSingleClause(e.get(0)), getNLFromSingleClause(e.get(1)));
      for (int i = 2; i < e.size(); i++) {
        cpe.addCoordinate(getNLFromSingleClause(e.get(i)));
      }
      cpe.setConjunction("and");

      return cpe;
    }
  }
예제 #4
0
 private NLGElement processTypes(
     Map<String, Set<String>> typeMap, Set<String> vars, boolean count, boolean distinct) {
   List<NPPhraseSpec> objects = new ArrayList<NPPhraseSpec>();
   // process the type information to create the object(s)
   for (String s : typeMap.keySet()) {
     if (vars.contains(s)) {
       // contains the objects to the sentence
       NPPhraseSpec object;
       object = nlgFactory.createNounPhrase("?" + s);
       Set<String> types = typeMap.get(s);
       if (types.size() == 1) {
         NPPhraseSpec np = getNPPhrase(types.iterator().next(), true);
         if (distinct) {
           np.addModifier("distinct");
         }
         object.addPreModifier(np);
       } else {
         Iterator<String> typeIterator = types.iterator();
         String type0 = typeIterator.next();
         String type1 = typeIterator.next();
         NPPhraseSpec np0 = getNPPhrase(type0, true);
         //                        if (distinct) {
         //                            np0.addModifier("distinct");
         //                        }
         NPPhraseSpec np1 = getNPPhrase(type1, true);
         //                        if (distinct) {
         //                            np1.addModifier("distinct");
         //                        }
         CoordinatedPhraseElement cpe = nlgFactory.createCoordinatedPhrase(np0, np1);
         while (typeIterator.hasNext()) {
           NPPhraseSpec np = getNPPhrase(typeIterator.next(), true);
           //                        if (distinct) {
           //                            np.addModifier("distinct");
           //                        }
           cpe.addCoordinate(np);
         }
         cpe.setConjunction("as well as");
         if (distinct) {
           cpe.addPreModifier("distinct");
         }
         object.addPreModifier(cpe);
       }
       object.setFeature(Feature.CONJUNCTION, "or");
       objects.add(object);
     }
   }
   if (objects.size() == 1) {
     // if(count) objects.get(0).addPreModifier("the number of");
     return objects.get(0);
   } else {
     CoordinatedPhraseElement cpe =
         nlgFactory.createCoordinatedPhrase(objects.get(0), objects.get(1));
     if (objects.size() > 2) {
       for (int i = 2; i < objects.size(); i++) {
         cpe.addCoordinate(objects.get(i));
       }
     }
     // if(count) cpe.addPreModifier("the number of");
     return cpe;
   }
 }
예제 #5
0
  /**
   * Generates a natural language representation for SELECT queries
   *
   * @param query Input query
   * @return Natural Language Representation
   */
  public DocumentElement convertSelectAndAsk(Query query) {
    // List of sentences for the output
    List<DocumentElement> sentences = new ArrayList<DocumentElement>();
    //        System.out.println("Input query = " + query);
    // preprocess the query to get the relevant types
    TypeExtractor tEx = new TypeExtractor(endpoint);
    Map<String, Set<String>> typeMap = tEx.extractTypes(query);
    //        System.out.println("Processed query = " + query);
    // contains the beginning of the query, e.g., "this query returns"
    SPhraseSpec head = nlgFactory.createClause();
    String conjunction = "such that";
    NLGElement body;
    NLGElement postConditions;

    List<Element> whereElements = getWhereElements(query);
    List<Element> optionalElements = getOptionalElements(query);
    // first sort out variables
    Set<String> projectionVars = typeMap.keySet();
    Set<String> whereVars = getVars(whereElements, projectionVars);
    // case we only have stuff such as rdf:type queries
    if (whereVars.isEmpty()) {
      whereVars = projectionVars;
    }
    Set<String> optionalVars = getVars(optionalElements, projectionVars);
    // important. Remove variables that have already been declared in first
    // sentence from second sentence
    for (String var : whereVars) {
      if (optionalVars.contains(var)) {
        optionalVars.remove(var);
      }
    }

    // process SELECT queries
    if (query.isSelectType()) {
      // process head
      // we could create a lexicon from which we could read these
      head.setSubject("This query");
      if (!tEx.isCount()) {
        head.setVerb("retrieve");
      } else {
        head.setVerb("retrieve the number of");
      }
    } // process ASK queries
    else {
      // process factual ask queries (no variables at all)
      if (typeMap.isEmpty()) {
        head.setSubject("This query");
        head.setVerb("ask whether");
        head.setObject(getNLFromElements(whereElements));
        head.setFeature(Feature.SUPRESSED_COMPLEMENTISER, true);
        phrases.add(head);
        sentences.add(nlgFactory.createSentence(head));
        return nlgFactory.createParagraph(sentences);
      }
      // process head
      // we could create a lexicon from which we could read these
      head.setSubject("This query");
      head.setVerb("ask for the existence of");
    }
    NLGElement e = processTypes(typeMap, whereVars, tEx.isCount(), query.isDistinct());
    head.setObject(e);
    // now generate body
    if (!whereElements.isEmpty()) {
      body = getNLFromElements(whereElements);
      // now add conjunction
      CoordinatedPhraseElement phrase1 = nlgFactory.createCoordinatedPhrase(head, body);
      phrase1.setConjunction("such that");
      // add as first sentence
      sentences.add(nlgFactory.createSentence(phrase1));
      phrases.add(phrase1);
      // this concludes the first sentence.
    } else {
      sentences.add(nlgFactory.createSentence(head));
      phrases.add(head);
    }

    // The second sentence deals with the optional clause (if it exists)
    if (optionalElements != null && !optionalElements.isEmpty()) {
      // the optional clause exists
      // if no supplementary projection variables are used in the clause
      if (optionalVars.isEmpty()) {
        SPhraseSpec optionalHead = nlgFactory.createClause();
        optionalHead.setSubject("it");
        optionalHead.setVerb("retrieve");
        optionalHead.setObject("data");
        optionalHead.setFeature(Feature.CUE_PHRASE, "Additionally, ");
        NLGElement optionalBody = getNLFromElements(optionalElements);
        CoordinatedPhraseElement optionalPhrase =
            nlgFactory.createCoordinatedPhrase(optionalHead, optionalBody);
        optionalPhrase.setConjunction("such that");
        optionalPhrase.addComplement("if such exist");
        sentences.add(nlgFactory.createSentence(optionalPhrase));

      } // if supplementary projection variables are used in the clause
      else {
        SPhraseSpec optionalHead = nlgFactory.createClause();
        optionalHead.setSubject("it");
        optionalHead.setVerb("retrieve");
        optionalHead.setObject(
            processTypes(typeMap, optionalVars, query.isDistinct(), query.isDistinct()));
        optionalHead.setFeature(Feature.CUE_PHRASE, "Additionally, ");
        if (!optionalElements.isEmpty()) {
          NLGElement optionalBody;
          optionalBody = getNLFromElements(optionalElements);
          // now add conjunction
          CoordinatedPhraseElement optionalPhrase =
              nlgFactory.createCoordinatedPhrase(optionalHead, optionalBody);
          optionalPhrase.setConjunction("such that");
          // add as second sentence
          optionalPhrase.addComplement("if such exist");
          sentences.add(nlgFactory.createSentence(optionalPhrase));
          phrases.add(optionalPhrase);
          // this concludes the second sentence.
        } else {
          optionalHead.addComplement("if such exist");
          sentences.add(nlgFactory.createSentence(optionalHead));
          phrases.add(optionalHead);
        }
      }
    }

    // The last sentence deals with the result modifiers
    if (query.hasHaving()) {
      SPhraseSpec modifierHead = nlgFactory.createClause();
      modifierHead.setSubject("it");
      modifierHead.setVerb("return exclusively");
      modifierHead.setObject("results");
      modifierHead.getObject().setPlural(true);
      modifierHead.setFeature(Feature.CUE_PHRASE, "Moreover, ");
      List<Expr> expressions = query.getHavingExprs();
      CoordinatedPhraseElement phrase =
          nlgFactory.createCoordinatedPhrase(modifierHead, getNLFromExpressions(expressions));
      phrase.setConjunction("such that");
      sentences.add(nlgFactory.createSentence(phrase));
    }
    if (query.hasOrderBy()) {
      SPhraseSpec order = nlgFactory.createClause();
      order.setSubject("The results");
      order.getSubject().setPlural(true);
      order.setVerb("be ordered by");
      List<SortCondition> sc = query.getOrderBy();
      if (sc.size() == 1) {
        Expr expr = sc.get(0).getExpression();
        if (expr instanceof ExprVar) {
          ExprVar ev = (ExprVar) expr;
          order.setObject(ev.toString());
        }
        if (sc.get(0).direction < 0) {
          order.addComplement("in descending order");
        } else {
          order.addComplement("in ascending order");
        }
      }
      phrases.add(order);
      sentences.add(nlgFactory.createSentence(order));
    }
    if (query.hasLimit()) {
      SPhraseSpec limitOffset = nlgFactory.createClause();
      long limit = query.getLimit();
      if (query.hasOffset()) {
        long offset = query.getOffset();
        limitOffset.setSubject("The query");
        limitOffset.setVerb("return");
        limitOffset.setObject("results between number " + limit + " and " + (offset + limit));
      } else {
        limitOffset.setSubject("The query");
        limitOffset.setVerb("return");
        if (limit > 1) {
          if (query.hasOrderBy()) {
            limitOffset.setObject("at most the first " + limit + " results");
          } else {
            limitOffset.setObject("at most " + limit + " results");
          }
        } else {
          if (query.hasOrderBy()) {
            limitOffset.setObject("at most the first result");
          } else {
            limitOffset.setObject("at most one result");
          }
        }
      }
      phrases.add(limitOffset);
      sentences.add(nlgFactory.createSentence(limitOffset));
    }

    DocumentElement result = nlgFactory.createParagraph(sentences);
    return result;
  }