1

我正在尝试在 GF 中生成以下句子: Jack wants to listen to a Taylor song 但正如我在 RGL 中看到的那样,PN -> NP这是获得正确名称的唯一解决方案。如何让 GF 输出带有限定词和宾语的专有名词。

另外我想知道为什么在 RGL PN中被称为专有名称而不是专有名词?

4

1 回答 1

1

该句中“Taylor”的句法功能是“song”的修饰语。所以分组不是“a Taylor”,而是“a song”,用 Taylor 作为修饰语:

  • 一首歌
  • 一首好歌
  • 泰勒的歌

这个答案不一定适用于英语以外的其他语言。但是还有很多其他的结构可以直接从 RGL 中使用,比如“a song by NP”。

艺术家数量有限

如果你有一组固定的艺术家,最简单的办法就是作弊,把他们变成英语的形容词。这是一个例子:

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

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

对于英文版,我们将 lincat 制作为Artistinto AP。这在英语中有效,因为形容词不变形,所以它只是一个字符串。

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") ;
}

按预期工作:

$ 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

请注意,如果您的乐队有自己的文章,您会得到Jack 想听一首披头士乐队的歌曲

艺术家作为修饰符与主题

您总是可以为 制作更复杂的 lincat Artist,这是一个示例。我们将在抽象语法中添加TheBeatlesas 。Artist我还添加了另一个功能,其中艺术家不仅是修饰符,而且是主题。

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

这是混凝土。我没有重用原来的 SongEng,因为我需要更改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)
        }
      } ;
}

这是它的输出。

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

如果你想让“The Beatles”变成复数形式,那么我们可以这样做。添加另一个重载实例mkArtist,在其中给它一个已经构造的 NP。然后您可以指定“The Beatles”实际上是复数形式。

  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")) ;
      } ;

这将为您提供以下输出:

Song2> l isGood TheBeatles 
The Beatles are good

任意字符串作为艺术家

最后,如果您想使用任意字符串作为艺术家,您可以使用字符串文字。对于该independent领域,它工作得很好: 符号模块中有将字符串文字传递给 NP 的函数。

但是,对于该modifier领域,您需要在 API 之外进行操作——这里是如何以稍微不那么不安全的方式进行操作的说明,但如果 R​​GL 内部发生变化,仍不能保证它是稳定的。

除了免责声明,这是最终的扩展。

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

还有混凝土。这次我们确实扩展了 Song2Eng,因为不需要更改 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
      } ;
}

让我们看看它是如何工作的:

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

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

只是一个警告:用空格线性化字符串非常有效,所以这没关系:

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

但是你不能用空格解析字符串文字。

Song3> p "Backstreet Boys is good"
The parser failed at token 2: "Boys"
于 2021-03-22T05:50:02.697 回答