对于大学考试修订,我在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'是包含在人员结构的文件结构中的列表结构。
为什么这不符合我的预期?
关于我还能在这里尝试什么的任何建议?
答案 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 - 程序的声明和操作语义不再相同。语言纯粹主义者可能会发现这令人不安 - “真正的程序员”并不关心。)