public SPhraseSpec getNLForTriple2(Triple t) { SPhraseSpec p = nlgFactory.createClause(); // process subject if (t.getSubject().isVariable()) { p.setSubject(t.getSubject().toString()); } else { p.setSubject(getNPPhrase(t.getSubject().toString(), false)); } // process predicate if (t.getPredicate().isVariable()) { p.setVerb("be related via " + t.getPredicate().toString() + " to"); } else { p.setVerb(getVerbFrom(t.getPredicate())); } // process object if (t.getObject().isVariable()) { p.setObject(t.getObject().toString()); } else if (t.getObject().isLiteral()) { p.setObject(t.getObject().getLiteralLexicalForm()); } else { p.setObject(getNPPhrase(t.getObject().toString(), false)); } p.setFeature(Feature.TENSE, Tense.PRESENT); return p; }
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; } }
/** * 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; }
private NLGElement getNLGFromAggregation(ExprAggregator aggregationExpr) { SPhraseSpec p = nlgFactory.createClause(); Aggregator aggregator = aggregationExpr.getAggregator(); Expr expr = aggregator.getExpr(); if (aggregator instanceof AggCountVar) { p.setSubject("the number of " + expr); } return p.getSubject(); }
/** * Generates a natural language representation for a query * * @param query Input query * @return Natural Language Representation */ @Override public DocumentElement convert2NLE(Query query) { phrases = new ArrayList<NLGElement>(); if (query.isSelectType() || query.isAskType()) { return convertSelectAndAsk(query); } else if (query.isDescribeType()) { return convertDescribe(query); } else { SPhraseSpec head = nlgFactory.createClause(); head.setSubject("This framework"); head.setVerb("support"); head.setObject("the input query"); head.setFeature(Feature.NEGATED, true); DocumentElement sentence = nlgFactory.createSentence(head); DocumentElement doc = nlgFactory.createParagraph(Arrays.asList(sentence)); return doc; } }
@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; }
public SPhraseSpec getNLForTriple(Triple t) { SPhraseSpec p = nlgFactory.createClause(); // process predicate then return subject is related to if (t.getPredicate().isVariable()) { if (t.getSubject().isVariable()) { p.setSubject(t.getSubject().toString()); } else { p.setSubject(getNPPhrase(t.getSubject().toString(), false)); } p.setVerb("be related via " + t.getPredicate().toString() + " to"); if (t.getObject().isVariable()) { p.setObject(t.getObject().toString()); } else { p.setObject(getNPPhrase(t.getObject().toString(), false)); } } else { NLGElement subj; if (t.getSubject().isVariable()) { subj = nlgFactory.createWord(t.getSubject().toString(), LexicalCategory.NOUN); } else { subj = nlgFactory.createWord( uriConverter.convert(t.getSubject().toString()), LexicalCategory.NOUN); } // subj.setFeature(Feature.POSSESSIVE, true); // PhraseElement np = nlgFactory.createNounPhrase(subj, // getEnglishLabel(t.getPredicate().toString())); p.setSubject( realiser.realise(subj) + "\'s " + uriConverter.convert(t.getPredicate().toString())); p.setVerb("be"); if (t.getObject().isVariable()) { p.setObject(t.getObject().toString()); } else if (t.getObject().isLiteral()) { p.setObject(t.getObject().getLiteralLexicalForm()); } else { p.setObject(getNPPhrase(t.getObject().toString(), false)); } } p.setFeature(Feature.TENSE, Tense.PRESENT); return p; }
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; } }
/** * 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; } }
public NLGElement getNLFromSingleClause(Element e) { if (e instanceof ElementPathBlock) { ElementPathBlock epb = (ElementPathBlock) e; List<Triple> triples = new ArrayList<Triple>(); // get all triples. We assume that the depth of union is always 1 for (TriplePath tp : epb.getPattern().getList()) { Triple t = tp.asTriple(); triples.add(t); } return getNLForTripleList(triples, "and"); } // if clause is union clause then we generate or statements else if (e instanceof ElementUnion) { CoordinatedPhraseElement cpe; // cast to union ElementUnion union = (ElementUnion) e; List<Triple> triples = new ArrayList<Triple>(); // get all triples. We assume that the depth of union is always 1 for (Element atom : union.getElements()) { ElementPathBlock epb = ((ElementPathBlock) (((ElementGroup) atom).getElements().get(0))); if (!epb.isEmpty()) { Triple t = epb.getPattern().get(0).asTriple(); triples.add(t); } } return getNLForTripleList(triples, "or"); } // if it's a filter else if (e instanceof ElementFilter) { SPhraseSpec p = nlgFactory.createClause(); ElementFilter filter = (ElementFilter) e; Expr expr = filter.getExpr(); return getNLFromSingleExpression(expr); } return null; }
/** * Takes a DBPedia class and returns the correct label for it * * @param className Name of a class * @return Label */ public NPPhraseSpec getNPPhrase(String className, boolean plural) { NPPhraseSpec object = null; if (className.equals(OWL.Thing.getURI())) { object = nlgFactory.createNounPhrase(GenericType.ENTITY.getNlr()); } else if (className.equals(RDFS.Literal.getURI())) { object = nlgFactory.createNounPhrase(GenericType.VALUE.getNlr()); } else if (className.equals(RDF.Property.getURI())) { object = nlgFactory.createNounPhrase(GenericType.RELATION.getNlr()); } else if (className.equals(RDF.type.getURI())) { object = nlgFactory.createNounPhrase(GenericType.TYPE.getNlr()); } else { String label = uriConverter.convert(className); if (label != null) { object = nlgFactory.createNounPhrase(label); } else { object = nlgFactory.createNounPhrase(GenericType.ENTITY.getNlr()); } } object.setPlural(plural); return object; }
private NLGElement getNLFromSingleExpression(Expr expr) { SPhraseSpec p = nlgFactory.createClause(); return expressionConverter.convert(expr); // process REGEX /*if (expr instanceof E_Regex) { E_Regex expression; expression = (E_Regex) expr; String text = expression.toString(); text = text.substring(6, text.length() - 1); String var = text.substring(0, text.indexOf(",")); String pattern = text.substring(text.indexOf(",") + 1); p.setSubject(var); p.setVerb("match"); p.setObject(pattern); } else if (expr instanceof ExprFunction1) { boolean negated = false; if (expr instanceof E_LogicalNot) { expr = ((E_LogicalNot) expr).getArg(); negated = true; } if (expr instanceof E_Bound) { p.setSubject(((E_Bound) expr).getArg().toString()); p.setVerb("exist"); } if (negated) { p.setFeature(Feature.NEGATED, true); } } //process language filter else if (expr instanceof E_Equals) { E_Equals expression; expression = (E_Equals) expr; String text = expression.toString(); text = text.substring(1, text.length() - 1); String[] split = text.split("="); String arg1 = split[0].trim(); String arg2 = split[1].trim(); if (arg1.startsWith("lang")) { String var = arg1.substring(5, arg1.length() - 1); p.setSubject(var); p.setVerb("be in"); if (arg2.contains("en")) { p.setObject("English"); } } else { p.setSubject(arg1); p.setVerb("equal"); p.setObject(arg2); } } else if (expr instanceof ExprFunction2) { Expr left = ((ExprFunction2) expr).getArg1(); Expr right = ((ExprFunction2) expr).getArg2(); //invert if right is variable or aggregation and left side not boolean inverted = false; if (!left.isVariable() && (right.isVariable() || right instanceof ExprAggregator)) { Expr tmp = left; left = right; right = tmp; inverted = true; } //handle subject NLGElement subject = null; if (left instanceof ExprAggregator) { subject = getNLGFromAggregation((ExprAggregator) left); } else { if (left.isFunction()) { ExprFunction function = left.getFunction(); if (function.getArgs().size() == 1) { left = function.getArg(1); } } subject = nlgFactory.createNounPhrase(left.toString()); } p.setSubject(subject); //handle object if (right.isFunction()) { ExprFunction function = right.getFunction(); if (function.getArgs().size() == 1) { right = function.getArg(1); } } if (right.isVariable()) { p.setObject(right.toString()); } else if (right.isConstant()) { if (right.getConstant().isIRI()) { p.setObject(getEnglishLabel(right.getConstant().getNode().getURI())); } else if (right.getConstant().isLiteral()) { p.setObject(right.getConstant().asNode().getLiteralLexicalForm()); } } //handle verb resp. predicate String verb = null; if (expr instanceof E_GreaterThan) { if (inverted) { verb = "be less than"; } else { verb = "be greater than"; } } else if (expr instanceof E_GreaterThanOrEqual) { if (inverted) { verb = "be less than or equal to"; } else { verb = "be greater than or equal to"; } } else if (expr instanceof E_LessThan) { if (inverted) { verb = "be greater than"; } else { verb = "be less than"; } } else if (expr instanceof E_LessThanOrEqual) { if (inverted) { verb = "be greater than or equal to"; } else { verb = "be less than or equal to"; } } else if (expr instanceof E_NotEquals) { if (left instanceof E_Lang) { verb = "be in"; if (right.isConstant() && right.getConstant().asString().equals("en")) { p.setObject("English"); } } else { verb = "be equal to"; } p.setFeature(Feature.NEGATED, true); } p.setVerb(verb); } //not equals else { return null; } return p;*/ }
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; } }
/** * 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; }