The input notation to jsRealB realizer was originally designed to be a valid JavaScript program reflecting the traditional constituent syntax formalism which is quite convenient when the NLG system is written in Javascript. Given the fact that Python has become the lingua franca of NLP, we have developed an alternative JSON input format for jsRealB that can be built using the standard Python JSON API.
This is useful, but for Python applications, it is now much more convenient to use pyrealb
, written in Python, which implements the same capabilities as jsRealB
.
The following table shows how JSON values are mapped to Python values. Using the JSON API, it is relatively easy to create in Python a value that can be serialized into JSON that can be sent to a jsRealB HTTP server using the JSON input format.
JSON | Python |
---|---|
object | dict |
array | list |
string | string |
number | number |
true | True |
false | False |
null | None |
Using the classical constituent based notation is quite similar to Python constructors which are called by simply writing their name, usually starting with a capital letter. Similarly to Javascript, the created object can use the dot notation to call its members. So we developed a constituent based notation for creating Python data structures which is similar (in fact the same, except for False, True, None
in Python that are coded as false, true, null
in JavaScript) as the one used for the jsRealB Javascript version. Of course, in Python this notation is only used for creating a data structure, while in Javascript it can be serialized directly.
The system is based on three main classes: Constituent
with two subclasses, Terminal
and Phrase
. The Phrase
is subclassed to define the jsRealB constructors: S
, SP
, NP
,... Terminal
is subclassed to define D
, N
, V
, ... See the jsRealB documentation for details.
With this notation, it is now easy to create Python data structures using the usual jsRealB notation. For example
sent = S( # Sentence
Pro("him").c("nom"), # Pronoun (citation form), nominative case
VP(V("eat"), # Verb at present tense by default
NP(D("a"), # Noun Phrase, Determiner
N("apple").n("p") # Noun plural
).tag("em") # add an <em> tag around the NP
))
creates a Python data structure that can be serialized as string with the JSON representation with str(sent)
to return
'{"phrase":"S","props":{},"elements":[{"terminal":"Pro","props":{"c":"nom"},"lemma":"him"},{"phrase":"VP","props":{},"elements":[{"terminal":"V","props":{},"lemma":"eat"},{"phrase":"NP","props":{"tag":"em"},"elements":[{"terminal":"D","props":{},"lemma":"a"},{"terminal":"N","props":{"n":"p"},"lemma":"apple"}]}]}]}'
A pretty printed JSON string can be printed with print(sent.pp())
{"phrase":"S",
"elements":[{"terminal":"Pro","lemma":"him","props":{"c":"nom"}}},
{"phrase":"VP",
"elements":[{"terminal":"V","lemma":"eat"},
{"phrase":"NP","props":{"tag":"em"},
"elements":[{"terminal":"D","lemma":"a"},
{"terminal":"N","lemma":"apple","props":{"n":"p"}}}]}]}]}
A pretty-printed constituent notation of the expression can be printed with print(sent.show())
S(Pro("him").c("nom"),
VP(V("eat"),
NP(D("a"),
N("apple").n("p")).tag("em")))
Note that this string is recomputed from the internal data structure so it is not necessarily the one used as input, especially if it has been modified by the program since its creation. Calling show(-1)
will create the expression on a single line which is shorter for sending to the web server.
jsRealB(exp,lang="en")
sends the Python expression exp
(either in JSON or in jsRealB like fashion produced by show
) to an HTTP jsRealB server and returns the realized string. By default, the jsRealB server runs on http://127.0.0.1:8081
. lang
sets the realization language, English by default.
Although the JSON notation is a static description of a structures, the add(self,elements,ix=None)
method of the Phrase
class can modify an existing structure as it can be in Javascript. ix
is the position at which the new element will be added within the current elements. When not specified it is added at the end. For example, after the following definitions:
apple = NP(D("a"),N("apple"))
boy = NP(D("the"),N("boy"))
the call
jsRealB(S(VP().add(V("love")).add(apple)).add(boy.n("p"),0))
creates the following structure
S(NP(D("the"),
N("boy")).n("p"),
VP(V("love"),
NP(D("a"),
N("apple"))))
which is realized as
'The boys love an apple.'
Phrase
parameterIt can be convenient to generate Phrase
parameters systematically using lists with possibly None
values that should be ignored when creating the parameters. So Python phrase constructors will insert the values within a list as parameter and ignore None
values; it will also flatten any embedded list. For example:
NP(D("the"),[A("nice"),None,A("little")],[N("cat")])
is equivalent to
NP(D("the"),A("nice"),A("little"),N("cat"))
Initially, the realization language is set by the server. The option set_lang("en|fr")
can set the realization language for an expression and its children. This facility for bilingual realization is only available when JSON is sent to the server.
To add these functions to a Python 3 program. First copy this file in your directory, then add this to your program
from jsRealBclass import N,A,Pro,D,Adv,V,C,P,DT,NO,Q, NP,AP,AdvP,VP,CP,PP,S,SP, Constituent, Terminal, Phrase, jsRealB
Guy Lapalme, September 2020