% 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).
因此,我正在尝试返回该小组的导演姓名首字母和姓氏,该小组正好有两名非导演音乐家拉 fiddle 。
到目前为止我有这个
hasTwoViolinists(Initial,Surname):- group(_,musician(Initial,Surname,_),[musician(_,_,cv(_,_,violin)),musician(_,_,cv(_,_,violin))]).
这只会返回只有两个 fiddle 手的组,这不是我要找的
任何帮助将不胜感激
最佳答案
我做的第一件事是了解您的数据结构,并注意到找到恰好有两个 fiddle 手的音乐家列表将是最内在的规则,所以我开始这样做。
下面是一个规则,用于在列表中恰好找到两个项目。它需要得到增强,才能在 fiddle 家的音乐家名单上工作。
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是逻辑编程的 friend 。
提示 2:
创建一个谓词,当音乐家是 fiddle 家时返回 true,当音乐家不是 fiddle 家时返回 false。
is_violinist(musician(o, messiaen, cv(5, paris_chamber, violin))).
是的。
is_violinist(musician(m, ravel, cv(10, paris_chamber, piano))).
错误。
提示 3:
find
使用了两个谓词。
项目 = H 和
项目\= H
当它们被替换为is_violinist
时会发生什么
供引用:
=
\=
\+和没有一样。
提示 4:
既然您可以找到音乐家和两位 fiddle 手,您如何使用它来找到乐队?
提示 5:
既然您可以找到由两位 fiddle 手组成的小组,您如何使用它来查找导演的姓名首字母和姓氏?
提示代码。抱歉格式化,limits of markdown .
2.
is_violinist(musician(_,_,cv(_,_,violin))).
3.
% 当 Count 恰好等于 Total 且列表为空时为真。
find_v(C,C,[]).
% 当列表头部的 is_violinist 为真时,增加计数并执行下一项。
find_v(总计,计数,[H|T]):-
is_violinist(H),
Count1 是 Count + 1,
find_v(Total,Count1,T).
% 当列表头部的 is_violinist 不为真时执行下一项。
find_v(总计,计数,[H|T]):-
\+ is_violinist(H),
find_v(总计,计数,T)。
4.
查找组(组):-
组(组,_,音乐家),
find_v(2,0,音乐家)。
5.
find_director(姓名首字母,姓氏):-
group(_,musician(Initial,Surname,_),Musicians),
find_v(2,0,音乐家)。
关于list - 如何检查 Prolog 列表中的两个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41702732/