【问题标题】:Create a list from a Prolog DCG从 Prolog DCG 创建列表
【发布时间】:2019-05-19 11:35:17
【问题描述】:

我不知道如何使用定义的 DCG 创建一个包含已用于形成句子的元素的列表。

假设我们有以下 DCG:

father --> [Peter].
mother --> [Isabel].

child --> [Guido].
child --> [Claudia].

verb --> [is].
relation --> [father, of].
relation --> [mother, of].

pronoun --> [he].
pronoun --> [she].

adjective --> [a, male].
adjective --> [a, female].

s --> father, verb, relation, child.
s --> mother, verb, relation, child.
s --> pronoun, verb, adjective.

查询语句如下: phrase(s, [peter, is, father, of, guido]), phrase(s, [he, is, a, male]). 返回true。

我如何创建和维护这个执行语句的元素列表,以便在执行以下语句时获得false(因为彼得是男性,请注意she而不是he):

phrase(s, [peter, is, father, of, guido]), phrase(s, [she, is, a, female]).

本题使用与here相同的例子。

【问题讨论】:

  • 我已经添加了一个例子来说明这可能是如何工作的。以后,如果您想了解更多信息,请打开一个新问题。

标签: list prolog dcg


【解决方案1】:

DCG 的正确接口是通过phrase/2,phrase/3 的简化版本:

?- phrase(s, X).
X = [_8304, is, father, of, _8328] ;
X = [_8304, is, father, of, _8328] ;
X = [_8304, is, mother, of, _8328] ;
% etc

_8404 变量来自father --> [Peter]. 之类的规则,因为Peter 中还有一个变量(变量以_ 或大写字母开头。您可以通过将原子转义为'Peter' 来解决此问题- 另请参阅您提出的其他问题)。

短语的第一个名称是DCG规则,第二个参数是列表。当您使用特定列表作为第二个参数时,答案替换为空,Prolog 仅报告它可以派生列表。在我的示例中,我使用了变量 X 并获得了可能的替换,可以派生。

可以将约束添加为用大括号括起来的目标:

dupnum(X) --> 
   { member(X, [0,1,2,3,4,5,6,7,8,9]) },
   [X,X].

导致

?- phrase(dupnum(X), Y).
X = 0,
Y = [0, 0] ;
X = 1,
Y = [1, 1] ;
% etc

该示例还显示 DCG 产生式可以包含参数,您可以使用这些参数来传播解析树或一些一般解析上下文。

【讨论】:

  • 事实上,我想确保某些替换不应该被接受。例如,在执行某些两个句子后,它应该区分 he 和 she(请参阅顶部的已编辑问题)。
  • 这就是为什么我提到您可以将上下文作为参数传递给 DCG 规则:在您的情况下,上下文将包含有关解析的最后一个句子的信息。当您遇到指示代词时,您需要在上下文中查找可能的候选词。通常这是在第二次解析过程中完成的,此时您已经掌握了有关句子结构的更多信息。
  • 再说明:你是在对一个句子序列进行推理,所以你还需要为这个序列做一个规则。两个例句本身都很好,只有一个跟随另一个它不应该工作。
  • 我同意你传递上下文的想法(这是一个包含已解析句子元素的列表)。但我不知道如何将相同的上下文从前一个解析的句子传递到下一个将要解析的句子。
  • 你需要一个描述多个句子的规则。
【解决方案2】:

为了解决后来添加的额外问题:您可以通过添加其他参数来传递信息,但您需要描述句子的顺序。例子phrase(s, [peter, is, father, of, guido]), phrase(s, [he, is, a, male])应该成功,不应该成功的是两个句子一个接一个phrase(ss, [peter, is, father, of, guido, '.', he, is, a, male,'.'])(或者它可能成功,留下“他”作为我们不认识的人的参考。这完全取决于我们有多严格与上下文有关。)。

要正确地做到这一点,我们需要跳很多圈。首先,我们需要在 DCG 规则中添加解析信息。例如,np(np([A,O],object)) --> %... 会将文章后跟一个对象解析为结构np([A,O],object)。让我们用它解析['a', 'male']和[guido]:

?- phrase(np(NP), [a, male]).
NP = np([article(a), object(male, male)], object) ;
false.

?- phrase(np(NP), [guido]).
NP = np([name(guido, male)], name) ;
false.

np 的第一个参数是一个列表,因为其他 np 规则只有在组件上。请注意,我们将性别作为属性添加到name 和object。在其他语言中,例如法语,文章也有一个需要与对象一致的性别,但在英语中我们可以把它放在一边。更复杂的实现也会考虑对象是单数还是复数(动词的不同模式也是如此)。

对于动词,我们需要区分它们需要多少宾语名词短语。这是通过检查is_transitive/1、is_intransitive/1 和is_bitransitive/1 完成的。

为指示代词找到一个好的解决方案很难:代词不需要指代前面的主语,例如在“Gaile 与 Peter 结婚。他比她年长。”中。它甚至根本不需要参考最后一句话,例如“彼得是他想去的地方。”。这意味着 a) 您应该事先决定,您实际上想要涵盖哪些情况; b) 当您拥有完整的结构化信息时,最好在第二次解析运行中做出这些决定。这反映了syntactic, semantic and pragmatic reasoning 之间的语言区别,我会将您想要解决的问题归类为实用问题,这取决于其他两个步骤。

我在这里的解决方案只是将您想要做出的特定决定合并到单个解析运行中,以ss DCG 规则的可读性为代价:我们添加了一个额外的参数来收集已经解析的句子,a所谓的蓄能器。当我们开始解析时,历史记录是空的,这反映在规则ss(S) --> ss(S,[]). 上。对于实际规则,我们需要区分当前句子是否以指示代词开头。在第一种情况下,我们需要解决它,我们在这里通过查看前一句中可能的性别一致的名词短语来解决它。有了这个机器,我们就可以解析句子[peter, is, a father, '.', he, is a father,'.']:

?- phrase(ss(Tree), [peter,is,a,father,'.', he, is, a, father, '.']).
Tree = [s(np([name(peter, male)], name), vp([verb(is), np([article(a), object(father, male)], object)])), s(np([pronoun(he, male)], dpronoun), vp([verb(is), np([article(a), object(..., ...)], object)]))] ;

但我们无法解析[peter,is,a,father,'.', she, is, a, father, '.']:

?- phrase(ss(Tree), [peter,is,a,father,'.', she, is, a, father, '.']).
false.

在适当的语义/语用分析中,我们会用实际引用的名词短语来丰富代词短语,但这将作为对原始分析树的重写来完成。代码如下:

%%%% utility predicates
% gender_of(X,Y) is true if X is the gender of the syntax tree node Y
gender_of(X,name(_,X)).
gender_of(X,pronoun(_,X)).
gender_of(X,object(_,X)).
gender_of(G,np([X],_)) :-
    gender_of(G,X).
gender_of(G,np([_,X],_)) :-
    gender_of(G,X).

% nps_of(X,Y) is true if X is the list of nps occurring in the syntax tree node Y
nps_of([],vp([_])).
nps_of([NP],vp([_,NP])).
nps_of([NP|Rest],s(NP,VP)) :-
    nps_of(Rest, VP).

% nountype_of(X,Y) is true if X is the type of the np node Y
nountype_of(X, np(_,X)).

% is_intransitive(X) is true if the verb X does not require an object phrase
is_intransitive(is).
is_intransitive(walk).
% is_transitive(X) is true if the verb X requires an object phrase
is_transitive(is).
% is_bitransitive(X) is true if the verb X requires two object phrases
is_bitransitive(is).

%%%% DCG rules

% name are distinct from objects because they do not require articles
name(name(peter,male)) --> [peter].
name(name(isabel,female)) --> [isabel].
name(name(guido,male)) --> [guido].
name(name(claudia,female)) --> [claudia].

% nouns that require an article
object(object(mother,female)) --> [mother].
object(object(father,male)) --> [father].
object(object(male,male)) --> [male].
object(object(female,female)) --> [female].

% verbs
verb(verb(is)) --> [is].
verb(verb(walk)) --> [walks].

% pronouns
pronoun(pronoun(he,male)) --> [he].
pronoun(pronoun(she,female)) --> [she].

% articles
article(article(a)) -->
    [a].
article(article(the)) -->
    [the].

% noun phrases
np(np([A,O],object)) -->
    article(A),
    object(O).
np(np([N],name)) -->
    name(N).
np(np([PN], dpronoun)) -->
    pronoun(PN).

% verb phrases
vp(vp([V,NP])) -->
    verb(V),
    { V = verb(Name), is_transitive(Name) },
    np(NP).
vp(vp([V])) -->
    verb(V),
    { V = verb(Name), is_intransitive(Name) }.

end -->
    ['.'].

% a single sentence
s(s(NP,VP)) -->
    np(NP),
    vp(VP),
    end.

% a list of sentences, with accumulator
ss([],_Acc) -->
    [].
ss([S|Sentences],[]) -->
    s(S),
    ss(Sentences, [S]).
ss([S|Sentences], [LastS | Acc]) -->
    { S = s(np([Pronoun], dpronoun),_) },
    s(S),
    { gender_of(G, Pronoun), nps_of(LastNPS, LastS), member(LNP, LastNPS), gender_of(G,LNP) },
    ss(Sentences, [S, LastS | Acc]).
ss([S|Sentences], [LastS | Acc]) -->
    { S = s(NP,_), nountype_of(NT,NP), dif(NT,dpronoun) },
    s(S),
    ss(Sentences, [S, LastS | Acc]).

% wrapper of ss with empty accumulator
ss(S) -->
    ss(S,[]).

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-19
    • 1970-01-01
    相关资源
    最近更新 更多