如何检查Prolog列表中的两个元素

时间:2017-01-17 16:55:08

标签: list prolog

% The structure of a musical group takes the form
% group(Groupname, Director, Players).
% Players is a (possibly empty) list of musician structures,
% but excludes the musician structure for the Director.
% The Director is also a musician in the group.
% musician structures take the form
% musician(Initials,Surname,
% cv(Years_as_professional,Previous_orchestra,Instrument)).

group(classicalstars,
      musician(w,mozart,cv(10,vienna_phil,piano)),
      [musician(j,haydn,cv(32,vienna_phil,cello)), musician(j,bach,cv(40,dresden_chamber,viola))]).
group(romantics,
      musician(l,beethoven,cv(32,vienna_phil,piano)),
      [musician(f,liszt,cv(10,vienna_phil,violin))]).
group(nordicsounds,
      musician(e,grieg,cv(50,bergen_phil,piano)),
      [ ]).
group(impressions,
      musician(g,faure,cv(40,paris_chamber,violin)),
      [musician(c,saint-saens,cv(51,paris_chamber,violin)), musician(m,ravel,cv(10,paris_chamber,piano)), musician(o,messiaen,cv(5,paris_chamber,violin))]).

director(X):- group(_,X,_).

musicians(X):- group(_,_,Musicians),
              member(X,Musicians).

exists(X):- director(X);
            musicians(X).

因此,我正在尝试返回该小组的导演的姓氏和姓氏,该小组有两名非导演音乐家拉小提琴。
到目前为止我有这个

 hasTwoViolinists(Initial,Surname):- group(_,musician(Initial,Surname,_),[musician(_,_,cv(_,_,violin)),musician(_,_,cv(_,_,violin))]).  

只返回一个只有两位小提琴手的小组,这不是我想要的 任何帮助将不胜感激

1 个答案:

答案 0 :(得分:2)

我做的第一件事就是要理解你的数据结构,并注意到找到一个只有两名小提琴手的音乐家名单将是最重要的规则,所以我开始了。

这是一条规则,可以在列表中找到两个项目。需要加强它才能为小提琴家的音乐家名单工作。

find(C,_,C,[]).  % True when Count exactly equals Total and list is empty.

% When the head of the list is the item increment the count and do the next item.
find(Total,Item,Count,[H|T]) :-
      Item = H,
      Count1 is Count + 1,
      find(Total,Item,Count1,T).

% When the head of the list is not the item do the next item.
find(Total,Item,Count,[H|T]) :-
      Item \= H,
      find(Total,Item,Count,T).

% find(2,a,0,[a,b,a,c]).
% true .
%
% find(2,a,0,[a,a,a,c]).
% false.

注意:提示为spoilers,可以通过将鼠标移到它们上面来看到。 如果提示有一个代码解决方案,它低于所有提示,也作为扰流板,所以你必须移动鼠标才能看到它们。

提示1:

  

Predicates是您使用逻辑编程的朋友。

提示2:

  

创建一个谓词,当音乐家是小提琴手时返回true,当音乐家不是小提琴手时返回false。
 is_violinist(音乐家(o,messiaen,cv(5,paris_chamber,小提琴)))。
 真的。

 is_violinist(音乐家(m,ravel,cv(10,paris_chamber,piano)))。
 假的。

提示3:

  

find使用了两个谓词
 项目= H和
 项目\ = H

 将它们替换为is_violinist时会发生什么情况
 供参考:
 =
 \=
 \+与否相同。

提示4:

  

现在您可以找到两位小提琴手的音乐家,您如何使用它来找到小组?

提示5:

  

现在您可以找到两位小提琴手的小组,您如何使用它来找到导演的姓氏和姓氏?

提示代码。抱歉格式化limits of markdown

2

  

is_violinist(音乐家(_,_,cv(_,_,小提琴)))。

3

  

%当Count完全等于Total且列表为空时为真  find_v(C,C,[])。

 %当列表头部的is_violinist为真时,递增计数并执行下一个项目  find_v(总计,计数,[H | T]): -
       is_violinist(H),
       Count1是Count + 1,
       find_v(共,共1个记录,T)。

 %当列表头部的is_violinist不成立时,请执行下一项  find_v(总计,计数,[H | T]): -
       \ + is_violinist(H),
       find_v(总计,计数,T)。

4

  

find_group(组): -
       组(组,_,音乐家),
       find_v(2,0,音乐家)。

5

  

find_director(姓名,姓氏): -
       组(_,音乐家(初始,姓,_),音乐家),
       find_v(2,0,音乐家)。