【发布时间】:2017-12-07 20:39:32
【问题描述】:
我正在尝试在 Prolog 中创建一个句子解析器。我希望将句子解析为三个单独的列表,这些列表将与建议的结果相匹配。
例如,这里是我到目前为止想出的代码...
这是用于解析某些单词的词汇表:
det(the).
det(a).
det(an).
noun(cat).
noun(boy).
noun(girl).
noun(grandfather).
noun(person).
noun(mat).
noun(party).
noun(book).
noun(problem).
noun(father).
noun(student).
noun(golf).
noun(conversation).
noun(challenge).
noun(person).
noun(problem).
noun(sat).
verb(thrives).
verb(loves).
verb(likes).
prep(on).
prep(with).
adj(big).
adj(lonely).
adj(elderly).
adj(teenage).
adj(good).
adj(fat).
sentence(Sentence,sentence(Noun_Phrase,Verb_Phrase)):-
np(Sentence,Noun_Phrase,Rem),
vp(Rem,Verb_Phrase).
解析代码:
np([X|T],np(det(X),NP2),Rem):- /* Det NP2 */
det(X),
np2(T,NP2,Rem).
np(Sentence,Parse,Rem):- np2(Sentence,Parse,Rem). /* NP2 */
np(Sentence,np(NP,PP),Rem):- /* NP PP */
np(Sentence,NP,Rem1),
pp(Rem1,PP,Rem).
np2([H|T],np2(noun(H)),T):- noun(H). /* Noun */
np2([H|T],np2(adj(H),Rest),Rem):- adj(H),np2(T,Rest,Rem).
pp([H|T],pp(prep(H),Parse),Rem):- /* PP NP */
prep(H),
np(T,Parse,Rem).
vp([H| []], vp(verb(H))):- /* Verb */
verb(H).
vp([H|T], vp(verb(H), Rem)):- /* VP PP */
vp(H, Rem),
pp(T, Rem, _).
vp([H|T], vp(verb(H), Rem)):- /* Verb NP */
verb(H),
np(T, Rem, _).
然后我想用这样的东西从中获取输出......
?- sentence([a,very,young,boy,loves,a,manual,problem],Parse).
然后不知何故根据这样的事实提出礼物......
present(construction_kit, subject(very,young,boy), verb(loves), object(manual,problem)).
present(a_golfing_sweater, subject(young,father), verb(loves), object(golf)).
如您所见,我希望将其与现有的“construction_kit”相匹配。
【问题讨论】:
-
您没有使用 DCG 的任何原因?
-
Tomas 要问的是为什么你不使用 DCG 来实现你的语法。 DCG 使其更加透明。 例如,
sentence --> noun_phrase, verb_phrase. -
请参阅this 如何使用 DCG 编写此内容。 (DCG 正是 Prolog 存在的原因!)
-
这里的问题与你的整个方法有关,它不会扩展,而不是你的具体问题。我强烈建议您查看 Ivan Bratko 的书 Prolog Programming for AI 或 Pereira 的书 Prolog 和自然语言分析,它们都通过解析为 lambda 来满足更复杂的查询微积分表达式,然后计算它们。
-
@TomasBy DCG 是从哪里开始的,但我们在这里有一个巨大的解决方案空间和一个非常未指定的问题。顺便说一句,这本书的年代与质量或重要性无关,尤其是在 Prolog 中几乎没有什么变化。