列表交集,Prolog

时间:2011-04-08 00:08:29

标签: prolog

好的,所以这项计划必须完成3项任务:

  1. 解析以列表形式给出的句子,在这种情况下(在整个示例中)句子将是[the,traitorous,tostig_godwinson,was,slain]。 (它的历史,不要问!)所以这看起来像:

    sentence(noun_phrase(det(the),np2(adj(traitorous),np2(noun(tostig_godwinson)))),verb_phrase(verb(slain),np(noun(slain)))).
    
  2. 使用解析的句子提取主语,动词和对象,并作为列表输出,例如: [tostig_godwinson,was,slain]使用当前示例。我有这个工作,直到我尝试3号。

  3. 使用目标列表并将其与知识库进行比较,基本上回答您在第一时间提出的问题(请参阅下面的代码),因此使用此问题和知识库,程序将打印出'the_battle_of_stamford_bridge'为这是知识库中与相关列表匹配最多的句子

  4. 所以这就是我到目前为止的地方:

    history('battle_of_Winwaed',[penda,       king_of_mercia,was,slain,killed,oswui,king_of_bernicians, took_place, '15_November_1655']).
    
    history('battle_of_Stamford_Bridge',[tostig_godwinson,herald_hardrada,was,slain, took_place, '25_September_1066']).
    
    history('battle_of_Boroughbridge',[edwardII,defeated,earl_of_lancaster,execution, took_place, '16_march_1322']).
    
    history('battle_of_Towton',[edwardIV,defeated,henryVI,palm_Sunday]).
    
    history('battle_of_Wakefield',[richard_of_york, took_place, 
    '30_December_1490',was,slain,war_of_the_roses]).
    
    history('battle_of_Adwalton_Moor',[earl_of_newcastle,defeats,fairfax, took_place, '30_June_1643',battle,bradford,bloody]).
    
    history('battle_of_Marston_Moor',[prince_rupert,marquis_of_newcastle,defeats,fairfax,oliver_cromwell,ironsides, took_place, 
    '2_June_1644', bloody]).
    
    noun(penda).
    noun(king_of_mercia).
    noun(oswui).
    noun(king_of_bernicians).
    noun('15_November_1655').
    noun(tostig_godwinson).
    noun(herald_hardrada).
    noun('25_September_1066').
    noun(edwardII).
    noun(earl_of_lancaster).
    noun('16_march_1322').
    noun(edwardIV).
    noun(henryVI).
    noun(palm_Sunday).
    noun(richard_of_york).
    noun('30_December_1490').
    noun(war_of_the_roses).
    noun(earl_of_newcastle).
    noun(fairfax).
    noun('30_June_1643').
    noun(bradford).
    noun(prince_rupert).
    noun(marquis_of_newcastle).
    noun(fairfax).
    noun(oliver_cromwell).
    noun('2_June_1644').
    noun(battle).
    noun(slain).
    noun(defeated).
    noun(killed).
    adj(bloody).
    adj(traitorous).
    verb(defeats).
    verb(was).
    det(a).
    det(the).
    prep(on).
    
    best_match(Subject,Object,Verb):-
            history(X,Y),
            member(Subject,knowledgebase),
            member(Object,knowledgebase),
            member(Verb,knowledgebase),
            write(X),nl,
            fail.
    micro_watson:- write('micro_watson: Please ask me a question:'), read(X), 
    sentence(X,Sentence,Subject,Object,Verb),nl,write(Subject),nl,write(Verb),nl,write(Object).
    
    sentence(Sentence,sentence(Noun_Phrase, Verb_Phrase),Subject,Object,Verb):-
        np(Sentence,Noun_Phrase,Rem),
        vp(Rem,Verb_Phrase),
        nl, write(sentence(Noun_Phrase,Verb_Phrase)),
            noun(Subject),
        member(Subject,Sentence),
            noun(Object),
        member(Object,Rem),
        verb(Verb),
        member(Verb,Rem),
            best_match(Subject,Object,Verb).
    
    member(X,[X|_]).
    member(X,[_|Tail]):-
        member(X,Tail).
    np([X|T],np(det(X),NP2),Rem):-
        det(X),
        np2(T,NP2,Rem).
    np(Sentence,Parse,Rem):- np2(Sentence,Parse,Rem).
    np(Sentence,np(NP,PP),Rem):-
            np(Sentence,NP,Rem1),
            pp(Rem1,PP,Rem).
    np2([H|T],np2(noun(H)),T):-noun(H).
    np2([H|T],np2(adj(H),Rest),Rem):- adj(H),np2(T,Rest,Rem).
    pp([H|T],pp(prep(H),Parse),Rem):-
        prep(H),
        np(T,Parse,Rem).
    vp([H|[]],verb(H)):-
        verb(H).
    vp([H|T],vp(verb(H),Rest)):-
        verb(H),
        pp(T, Rest,_).
    vp([H|T],vp(verb(H),Rest)):-
        verb(H),
        np(T, Rest,_).
    

    正如我所说的那样,我的第二号工作直到我尝试了3号,现在它只是打印解析后的句子然后给我一个'错误:超出本地堆栈消息'任何帮助都非常感谢!所以在顶部是我们比较列表以找到最佳匹配的知识库,这些被best_match方法调用(虽然在这个阶段不正确),该方法在解析句子并提取后的句子方法之后立即执行。关键词。如果代码非常布局,我也很抱歉! 干杯

1 个答案:

答案 0 :(得分:3)

我认为发布此内容的人永远不会回来,我想提醒自己一些序言,所以在这里。

此代码存在两个主要问题,除了某些谓词中仍然存在一些逻辑问题。

问题1: 你忽略了单例警告,它们通常是不可忽视的。最佳匹配谓词应如下所示:

best_match(Subject,Object,Verb):-
        history(X,Y),
        member(Subject,Y),
        member(Object,Y),
        member(Verb,Y),
        write(X),nl,
        fail.

另一个警告是关于Sentence谓词中的sentence变量,所以它是这样的:

sentence(X,Subject,Object,Verb),nl,write(Subject),nl,write(Verb),nl,write(Object).

sentence(Sentence,Subject,Object,Verb):-

    np(Sentence,_,Rem),     
    vp(Rem,_),  
    nl, 
        noun(Subject),
    member(Subject,Sentence),
        noun(Object),
    member(Object,Rem),
    verb(Verb),
    member(Verb,Rem),
        best_match(Subject,Object,Verb).

问题2: 我假设您将np逻辑划分为np和np2以避免无限循环,但后来忘记在必要的地方应用此除法。最长的np子句应该是:

np(Sentence,np(NP,PP),Rem):-
        np2(Sentence,NP,Rem1),
        pp(Rem1,PP,Rem).

如果你真的想在那里允许更复杂的np,我怀疑,你可以这样做:

np(Sentence,np(NP,PP),Rem):-
  append(List1,List2,Sentence),
  List1\=[],
  List2\=[],
  np(List1,NP,Rem1),
  append(Rem1,List2,Rem2),
  pp(Rem2,PP,Rem).

这样你就不会一遍又一遍地使用相同的参数调用np,因为你确保每次检查的句子都更短。

小问题: (在修复无限循环问题后,程序如何工作)

  1. 重复最后一个vp
  2. 我不确定你的语法,例如为什么"defeated"是名词......
  3. 为了检查程序是否正常,我使用了句子[edwardIV,defeated,henryVI,on,palm_Sunday].

    我将"defeated"更改为动词,并将最后vp子句更改为:

    vp([H|T],vp(verb(H),Rest)):-
        verb(H),
        np(T,_,Rest1),      
        pp(Rest1, Rest,_).
    

    对于例句,我将battle_of_Boroughbridge和battle_of_Towton作为结果。