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

标签 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).

因此,我正在尝试返回该小组的导演姓名首字母和姓氏,该小组正好有两名非导演音乐家拉 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/

相关文章:

Prolog 单变量查询返回错误。为什么?

prolog - 编辑 Prolog 程序输出计算结果

r - 将复杂的列表列表转换为数据框列表

python - 在 python 中将列表中的条目格式化为 8 位二进制

c++ - 类不存在默认构造函数但未默认传递

printing - Prolog - 使用 format/2 打印列表列表

regex - 将奇数和偶数正则表达式结合到正则语法中?

python - python 分割数组

python - 如何在列表中查找多个最大值项

exception - 如何在 Prolog 中捕获超时异常