1

I'm trying to generate the following sentence in GF: Jack wants to listen to a Taylor song But as I can see in RGL PN -> NP is the only solution to get a proper name. How to get GF to output a proper noun with a determiner and an object.

Also I'm wondering why in RGL PN is being called proper name instead of proper noun?

1 Answers1

1

The syntactic function of "Taylor" in that sentence is a modifier to "song". So the grouping isn't "a Taylor", but rather "a song", with Taylor as a modifier:

  • a song
  • a good song
  • a Taylor song

This answer doesn't necessarily work in other languages than English. But there are plenty of other structures you can use straight out of RGL, like "a song by NP".

Limited set of artists

If you have a fixed set of artists, it's probably easiest to just cheat and make them into adjectives in English. Here's an example:

abstract Song = {
  flags startcat = Sentence ;
  cat
    Sentence ;
    Person ;
    Artist ;

  fun
    wantToListen : Person -> Artist -> Sentence ;
    Jack : Person ;
    Taylor, Ariana : Artist ;
}

For the English version, we make the lincat of Artist into AP. This works in English, because the adjectives don't inflect, so it'll just be a single string.

concrete SongEng of Song = open SyntaxEng, ParadigmsEng, LexiconEng in {

  lincat
    Sentence = Utt ;
    Person = NP ;
    Artist = AP ; -- cheat in English

  lin
    -- : Person -> Artist -> Sentence ;
    wantToListen person artist =
      let artistsSong : CN = mkCN artist song_N ;
          listenToSong : VP = mkVP listen_V2 (mkNP a_Det artistsSong) ;
       in mkUtt (mkS (mkCl person want_VV listenToSong)) ;

    -- : Person
    Jack = mkNP (mkPN "Jack") ;

    -- : Artist
    Taylor = mkAP (mkA "Taylor") ;
    Ariana = mkAP (mkA "Ariana") ;
}

Works as intended:

$ gf SongEng.gf
…
Song> gt | l -treebank
Song: wantToListen Jack Ariana
SongEng: Jack wants to listen to an Ariana song

Song: wantToListen Jack Taylor
SongEng: Jack wants to listen to a Taylor song

Note that if your bands have an article of their own, you'll get Jack wants to listen to a The Beatles song.

Artist as modifier vs. subject

You can always make a more complex lincat for Artist, here's an example. We'll add TheBeatles as an Artist in the abstract syntax. I also add another function, where the artist is not just a modifier, but the subject.

abstract Song2 = Song ** {
  flags startcat = Sentence ;
  fun
    TheBeatles : Artist ;
    isGood : Artist -> Sentence ;
}

And here's the concrete. I'm not reusing the original SongEng, because I need to change the lincat of Artist.

concrete Song2Eng of Song2 = open SyntaxEng, ParadigmsEng, LexiconEng in {

  lincat
    Sentence = Utt ;
    Person = NP ;
    Artist = LinArtist ; -- {independent : NP ; modifier : AP}

  lin
    -- : Person -> Artist -> Sentence ;
    wantToListen person artist =
      let artistsSong : CN = mkCN artist.modifier song_N ;
          listenToSong : VP = mkVP listen_V2 (mkNP a_Det artistsSong) ;
       in mkUtt (mkS (mkCl person want_VV listenToSong)) ;

    -- : Artist -> Sentence
    isGood artist = mkUtt (mkS (mkCl artist.independent good_A)) ;

    -- : Person
    Jack = mkNP (mkPN "Jack") ;

    -- : Artist
    Taylor = mkArtist "Taylor" ;
    Ariana = mkArtist "Ariana" ;
    TheBeatles = mkArtist "The Beatles" "Beatles" ;

  oper
    LinArtist : Type = {independent : NP ; modifier : AP} ;
    mkArtist = overload {
      mkArtist : Str -> Str -> LinArtist = \thebeatles, beatles -> {
        independent = mkNP (mkPN thebeatles) ;
        modifier = mkAP (mkA beatles)
        } ;
      mkArtist : Str -> LinArtist = \taylor -> {
        independent = mkNP (mkN taylor) ;
        modifier = mkAP (mkA taylor)
        }
      } ;
}

And here's the output from that.

Song2> gt | l
Ariana is good
Taylor is good
The Beatles is good
Jack wants to listen to an Ariana song
Jack wants to listen to a Taylor song
Jack wants to listen to a Beatles song

If you wanted to make "The Beatles" into plural, then we can do this. Add another overload instance of mkArtist, where you give it an already constructed NP. Then you can specify that "The Beatles" are, in fact, plural.

  oper
    mkArtist = overload {
      mkArtist : Str -> Str -> LinArtist = … ; -- same as before
      mkArtist : Str -> LinArtist = … ; -- same as before
      mkArtist : NP -> AP -> LinArtist = \thebeatles,beatles -> {
        independent = thebeatles ;
        modifier = beatles
        }
  lin
    TheBeatles =
      mkArtist
        (mkNP aPl_Det (mkN "The Beatles" "The Beatles"))
        (mkAP (mkA "Beatles")) ;
      } ;

And this gives you the following output:

Song2> l isGood TheBeatles 
The Beatles are good

Arbitrary strings as artists

Finally, if you want to use arbitrary strings as artists, you can use string literals. For the independent field, it works great: there are functions in the Symbolic module that take a string literal to NP.

However, for the modifier field, you need to go outside the API---here are instructions how to do it in a slightly less unsafe manner, but it's still not guaranteed to be stable, if the RGL internals ever change.

Disclaimers aside, here's the final extension.

abstract Song3 = Song2 ** {
  flags startcat = Sentence ;
  fun
    StringArtist : String -> Artist ;
}

And the concrete. This time we do extend Song2Eng, because there's no need to change the lincats.

concrete Song3Eng of Song3 = Song2Eng ** open SyntaxEng, LexiconEng, SymbolicEng in {
  lin
    -- : String -> Artist ;
    StringArtist string = {
      independent = symb string ; -- symb : String -> NP, from SymbolicEng
      modifier = <mkAP good_A : AP> ** {s = \\_ => string.s} -- hack
      } ;
}

Let's see how it works:

Song3> p "Jack wants to listen to a skhdgdjgfhjkdfhjsdf song"
wantToListen Jack (StringArtist "skhdgdjgfhjkdfhjsdf")

Song3> p "9ortge94yhjerh90fpersk is good"
isGood (StringArtist "9ortge94yhjerh90fpersk")

Just a warning: it works perfectly fine to linearise strings with spaces, so this is ok:

Song3> l isGood (StringArtist "Spice Girls")
Spice Girls is good

But you can't parse string literals with spaces.

Song3> p "Backstreet Boys is good"
The parser failed at token 2: "Boys"
inariksit
  • 1,232
  • 7
  • 13