0

对于大学考试的修订,我遇到了一个过去的论文问题,其中的 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 列表包含产生式“现在”时才找到匹配项,并且如您所见,它将返回首字母和姓氏如果至少 2 名员工 CV 包含“现在”生产,则为生产者。

所以,至少据我所见,它应该返回 c,卓别林生产者,对吧?因为这个团队的工作人员拥有包含“现在”作品的简历。

但是当我查询它时,例如

qii(Initial,Surname).

它返回“假”。

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

任何想法为什么这不能像我预期的那样工作?

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

4

1 回答 1

2

谓词还需要一个子句recurseTeam,即第一个参数是一个非空列表,但它的第一个元素是一个file不包含.now

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

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

recurseTeam([staff(_,_,file(_,_,CV))|List],Sum):-
    \+ member(now,CV),
    recurseTeam(List,Sum).

或者,可以!在第二个recurseTeam子句之后使用 cutmember(now,CV)并在第三个子句中使用 drop \+ member(now,CV)。这更有效,因为它避免了调用member(now,CV)两次。(但是请注意,这是一个红线——程序的声明性和操作性语义不再相同。语言纯粹主义者可能会觉得这令人不安——“真​​正的程序员”不在乎。)

于 2013-05-16T16:02:27.937 回答