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

时间:2014-10-14 11:07:15

标签: prolog

在我们的家庭作业中,我们得到了许多人,谁知道谁是数据库的形式, 像这样:

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

knows(person1,person2).
knows(person1,person3).
knows(person2,person4).
knows(person3,person5).

数据库可以包含任意数量的具有任何连接集的人。

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

即。

findall(Y, knows(Y, person1);knows(person1, Y), AllPeople).
    Y = [person2, person3] .

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

comb2(_,[]).
comb2([X|T],[X|Comb]):-comb2(T,Comb).
comb2([_|T],[X|Comb]):-comb2(T,[X|Comb]).

免责声明:我们从以下网址获取此代码段: http://ktiml.mff.cuni.cz/~bartak/prolog/combinatorics.html

comb2([person2, person3], X).
    X = [] ;
    X = [person2] ;
    X = [person2, person3] ;
    X = [person3] ;
    false.

问题是我们的代码检查了每个组合(看到组中没有人知道组中的其他人),并且一些测试用例的人最多有30个朋友(意思是天文数量)组合)。

我们需要的是一些方法来测试我们正在构建的组合中的任何人是否知道组合中的其他人,而我们正在构建它。

1 个答案:

答案 0 :(得分:0)

如果我已正确理解您的意思,答案是再次使用findall/3AllPeople来做到这一点。

% 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]]