Prolog查询未返回预期结果

时间:2013-05-16 15:50:13

标签: prolog

对于大学考试修订,我在Prolog数据库中遇到了过去的纸质问题,其中包含以下结构:

% The structure of a media production team takes the form
% team(Producer, Core_team, Production_assistant).
% Core_team is an arbitrarily long list of staff structures,
% but excludes the staff structures for Producer and
% and Production_assistant.
% staff structures represent employees and take the form
% staff(Surname,Initial,file(Speciality,Grade,CV)).
% CV is an arbitrarily long list of titles of media productions.

team(staff(lyttleton,h,file(music,3,[my_music,best_tunes,showtime])),
[staff(garden,g,file(musical_comedy,2,[on_the_town,my_music])),
staff(crier,b,file(musical_comedy,2,[on_the_town,best_tunes]))],
staff(brooke-taylor,t,file(music,2,[my_music,best_tunes]))).

team(staff(wise,e,file(science,3,[horizon,frontiers,insight])),
[staff(morcambe,e,file(science,3,[horizon,leading_edge]))],
staff(o_connor,d,file(documentary,2,[horizon,insight]))).

team(staff(merton,p,file(variety,2,[showtime,dance,circus])),
[staff(smith,p,file(variety,1,[showtime,dance,circus,my_music])),
staff(hamilton,a,file(variety,1,[dance,best_tunes]))],
staff(steaffel,s,file(comedy,2,[comedians,my_music]))).

team(staff(chaplin,c,file(economics,3,[business_review,stock_show])),
[staff(keaton,b,file(documentary,3,[business_review,insight])),
staff(hardy,o,file(news,3,[news_report,stock_show,target,now])),
staff(laurel,s,file(economics,3,[news_report,stock_show,now]))],
staff(senate,m,file(news,3,[business_review]))).

我必须写的一条规则如下:

  

返回团队中包含2的生产者的姓氏和姓氏   员工的简历包括名为“现在”的作品。

这是我的解决方案:

recurseTeam([],0).

recurseTeam[staff(_,_file(_,_,CV))|List],Sum):-
    member(now,CV),
    recurseTeam(List,Rest),
    Sum is Rest + 1.

query(Initial,Surname):-
    team(staff(Surname,Initial,file(Speciality,Grade,CV)),Core_team,Production_assistant),
    recurseTeam([staff(Surname,Initial,file(Speciality,Grade,CV)),Production_assistant|Core_team,Sum),
Sum >= 2.

我在这里的逻辑是我有一个递归谓词,它依次获取每个工作人员,只有当CV列表包含生产'now'时才能找到匹配,并且你可以看到它将返回Initial如果至少2名员工的CV包含“现在”的作品,则为制片人的姓氏。

所以,至少就我所知,它应该归还c,chaplin制作人,对吧?因为这个团队的工作人员拥有包含“现在”制作的简历。

但是当我查询它时,例如

qii(Initial,Surname).

它返回'false'。

当我删除“member(now,CV)”谓词时,它成功返回所有四个生成器。所以看来问题就在于这条规则。 Member是用于查询列表内容的内置谓词,'CV'是包含在人员结构的文件结构中的列表结构。

为什么这不符合我的预期?

关于我还能在这里尝试什么的任何建议?

1 个答案:

答案 0 :(得分:2)

你需要为recurseTeam谓词多一个子句,即第一个参数是非空列表的情况,但是它的第一个元素是不是<{1}}结构包含file

在当前版本中,now只要在列表中遇到这样的元素就会失败。

一种可能的解决方案是为recurseTeam添加以下第三个子句:

recurseTeam

或者,可以在recurseTeam([staff(_,_,file(_,_,CV))|List],Sum):- \+ member(now,CV), recurseTeam(List,Sum). 之后的第二个!子句中使用剪切recurseTeam,并在第三个子句中删除member(now,CV)。这样效率更高,因为它避免了两次调用\+ member(now,CV)。 (但请注意,这是一个red cut - 程序的声明和操作语义不再相同。语言纯粹主义者可能会发现这令人不安 - “真正的程序员”并不关心。)