我不知道如何创建一个列表,其中包含使用已定义的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
(因为Peter是男性,请注意she
而不是{{ 1}}):
he
此问题使用与here相同的示例。
答案 0 :(得分:0)
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生产中可以包含可用于传播解析树或某些常规解析上下文的参数。
答案 1 :(得分:0)
要解决稍后添加的其他问题:您可以通过添加其他参数来传递信息,但是您需要描述句子的顺序。示例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
完成。
要为指示代词找到一个好的解决方案很困难:代词不需要引用先前的主题,例如在“盖伊尔嫁给彼得。他比彼得大”中。甚至根本不需要引用最后一句话,例如在“彼得就是他想去的地方”中。这意味着a)您应该事先确定您实际要涵盖的情况,b)拥有完整的结构化信息后,最好在第二次分析中做出这些决定。这反映了syntactic, semantic and pragmatic reasoning之间的语言区别,我将您要解决的问题归为务实的,这取决于其他两个步骤。
在这里,我的解决方案只是将您要做出的特定决定合并到单个解析过程中,但要以ss
DCG规则的可读性为代价:我们添加了一个附加参数来收集已经解析的语句,即所谓的累加器。当我们开始解析时,历史记录为空,这由规则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,[]).