Prolog中的句子解析和匹配 [英] Sentence parsing and matching in Prolog

查看:75
本文介绍了Prolog中的句子解析和匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Prolog中创建一个句子解析器.我希望将该句子解析为三个单独的列表,并与建议的结果进行匹配.

I'm trying to create a sentence parser in Prolog. I want the sentence to be parsed into three separate lists that will be matched with a suggested outcome.

例如,这是我到目前为止提出的代码...

For example, here's the code I have come up with so far...

这是用于解析某些单词的词汇表:

This is the vocabulary which will be used to parse certain words:

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, _).

然后我想从中获得类似这样的输出...

I then want to get the output from this with something like this...

?- sentence([a,very,young,boy,loves,a,manual,problem],Parse).

然后从某种事实中提出礼物...

And then somehow suggest a present out of a fact like this...

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"相匹配.

As you can probably see, I would want to match this with the 'construction_kit' present.

推荐答案

让我们尝试将其缩小为一个小问题,以便我们了解如何解决.让我们从一个简单的语法开始.

Let's try and trim this down to a small problem so we can see how we might approach it. Let's start with a simpler grammar.

sentence(NP, VP) --> noun_phrase(NP), verb_phrase(VP).
noun_phrase(np(Noun, Adj)) --> det, adjectives(Adj), noun(Noun).

det --> [D], { det(D) }.
det --> [].

noun(N) --> [N], { noun(N) }.

adjectives([]) --> [].
adjectives([A|As]) --> adjective(A), adjectives(As).
adjective(A) --> [A], { adj(A) }.

verb_phrase(vp(Verb, Noun)) --> verb(Verb), noun_phrase(Noun).

verb(V) --> [V], { verb(V) }.

即使对于您的问题,这也不是一个完整的语法,但是它将解析一些句子:

This is not a complete grammar even for your problem, but it will parse some sentences:

?- phrase(sentence(NP,VP), [a,teenage,boy,loves,a,big,problem]).
NP = np(boy, [teenage]),
VP = vp(loves, np(problem, [big])) 

现在我们可以建立一个当前数据库.我现在只考虑名词短语的头部".

Now we can make a present database. I'm just going to consider the "head" of the noun phrase for now.

present('construction kit', boy, loves, problem).

现在,您可以部署一个非常简单的查询来尝试将其匹配:

Now you can deploy a very simple query to try and match them up:

?- phrase(sentence(np(Noun,_), vp(Verb, np(Object, _))),
   [a,teenage,boy,loves,a,big,problem]), 
   present(Suggestion, Noun, Verb, Object).
Noun = boy,
Verb = loves,
Object = problem,
Suggestion = 'construction kit' ;

现在,您可以立即看到最大的问题:如果尝试匹配更复杂的语法,则查询的复杂度将相应增加,从而将其转化为建议.解决此类问题的方法通常是在两个问题之间增加抽象,而这两个问题在复杂性上似乎越来越复杂,但这超出了此问题的范围.

Now you can see immediately your biggest problem: if you try to match a more complex grammar, you're going to have to have a corresponding increase in the complexity of your query which turns that into a suggestion. The solution to this kind of problem, where two things appear to increase in complexity in concert, is always to create an abstraction between them, but that is out of scope for this question.

编辑值得注意的是,如果您要构建通用推荐系统,则这不是现代方法.我会推荐本书 Programming Collective Intelligence (编程集体智能),以快速阅读一些以相当可读的Python为后盾的方法.

Edit It's worth noting that if you want to build a general recommendation system, this is not a modern approach. I would recommend the book Programming Collective Intelligence for a quick overview of several approaches, backed by fairly readable Python.

编辑是否很清楚使语法更复杂会导致匹配礼物的复杂性更高?

Edit Is it clear that making the grammar more complex will result in more complexity in matching presents?

对于初学者,我完全省略了介词短语的产生.我只是不包括在内.如果在那,是否会对建议产生影响?考虑一下这样的句子:一个爱编码的十几岁男孩爱一个大问题" —我的noun_phrase//1涵盖该案例的自然延伸将错过这个孩子的重要细节,这可能会导致您得到与礼物不同的礼物.施工集.

For starters, I have omitted entirely your prepositional phrase production. I just didn't include that. If it were there, would it have bearing on the suggestion? Consider a sentence like "a teenage boy who loves to code loves a big problem"—the natural extension of my noun_phrase//1 to cover this case will miss out on an important detail of this child which might lead you to a different present than the construction set.

假设您要处理该补充信息,则必须在phrase/3的第一个参数中添加更多模式.实际上,您可能会接受任何结果,然后将其发送到某种建议系统.

Supposing you want to handle that supplemental information, you will have to add more patterns to the first argument to phrase/3. In fact, you'll probably accept whatever comes out and then dispatch to some kind of suggestion system.

@TomasBy正确的一件事是,我们在这里使用非常简单的中间表示形式,即(名词,动词,宾语).但是,如果我们使语法更加复杂,那么我们将不得不在这种表示形式中捕获并处理更多的语法,这将增加建议系统的复杂性.我看不到如何扩展这种简单表示形式以处理介词短语,除非您只是将它们扔掉.

One thing @TomasBy gets right is that we are using a very simple intermediate representation here, which is just (noun,verb,object). But if we make the grammar more complex, we will have to capture and handle more of it in this representation which will raise the complexity of the suggestion system. I don't see how to extend this simple representation to handle prepositional phrases, for instance, unless you just throw them away.

这很简单,但是Prolog会为您完成.您只需在上面加载DCG并使用listing/0即可得到答案.

This is straightforward to do, but Prolog will do it for you. You can simply load the DCG above and use listing/0 to get the answer.

| ?- listing.

% file: user

sentence(A, B, C, D) :-
    noun_phrase(A, C, E),
    verb_phrase(B, E, D).

noun_phrase(np(A, B), C, D) :-
    det(C, E),
    adjectives(B, E, F),
    noun(A, F, D).

det([A|B], C) :-
    det(A),
    B = C.
det(A, A).

noun(A, [A|B], C) :-
    noun(A),
    B = C.

adjectives([], A, A).
adjectives([A|B], C, D) :-
    adjective(A, C, E),
    adjectives(B, E, D).

adjective(A, [A|B], C) :-
    adj(A),
    B = C.

verb_phrase(vp(A, B), C, D) :-
    verb(A, C, E),
    noun_phrase(B, E, D).

verb(A, [A|B], C) :-
    verb(A),
    B = C.

这篇关于Prolog中的句子解析和匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆