在Prolog中创建列表时检查(列表的)组合

在Prolog中创建列表时检查(列表的)组合,prolog,Prolog,在我们的家庭作业中,我们得到了一个数据库形式的一些人和谁知道谁, 像这样: person(person1). person(person2). person(person3). person(person4). person(person5). knows(person1,person2). knows(person1,person3). knows(person2,person4). knows(person3,person5). 数据库可以包含具有任何连接集的任意数量的人 我们有一个谓词

在我们的家庭作业中,我们得到了一个数据库形式的一些人和谁知道谁, 像这样:

person(person1).
person(person2).
person(person3).
person(person4).
person(person5).

knows(person1,person2).
knows(person1,person3).
knows(person2,person4).
knows(person3,person5).
数据库可以包含具有任何连接集的任意数量的人

我们有一个谓词(findall),它生成一个人(X)认识的人的列表:

i、 e

然后有一个谓词生成这些人的组合

comb2(_,[]).
comb2([X|T],[X|Comb]):-comb2(T,Comb).
comb2([_|T],[X|Comb]):-comb2(T,[X|Comb]).
免责声明:我们从以下网站获得此代码片段:

i、 e

问题是,我们的代码对每个组合都进行检查(以确保组中没有人知道组中的其他人),并且一些测试用例中的人最多有30个朋友(这意味着组合的数量是天文数字)


我们需要的是某种方法来测试我们正在构建的组合中是否有人在构建组合时认识组合中的其他人。

如果我正确理解了你的意思,那么答案就是再次使用
findall/3
所有人
来实现这一点

% Assume that your code is here..

knows(person2,person3).
knows(person3,person2).

group(G) :-
  G = [_,_|_],
  forall(
    ( member(A, G)
    , member(B, G)
    , A \== B), knows(A, B)).
对应查询为:

?- One = person1, 
  findall(E
    , knows(E, One)
    ; knows(One, E), AllPeople),
  findall(G, (comb2(AllPeople, G), group(G)), Groups).

  // ==> Groups = [[person2,person3]]
% Assume that your code is here..

knows(person2,person3).
knows(person3,person2).

group(G) :-
  G = [_,_|_],
  forall(
    ( member(A, G)
    , member(B, G)
    , A \== B), knows(A, B)).
?- One = person1, 
  findall(E
    , knows(E, One)
    ; knows(One, E), AllPeople),
  findall(G, (comb2(AllPeople, G), group(G)), Groups).

  // ==> Groups = [[person2,person3]]