所以,我仍然不完全理解prolog中的列表和递归是如何工作的,这可能就是我遇到这个问题的原因,但我甚至不知道如何解决这个问题。
有一个朋友列表。
f(a,b).
f(a,c).
f(a,d).
f(b,c).
f(b,e).
f(b,f).
f(c,e).
f(c,g).
f(g,e).
etc..
我必须通过其他人和两个朋友的朋友找到某人是朋友。
如果我这样做的例子
fof(a,e, List).
然后我应该
List = [a, b, e];
List = [a, c, e];
List = [a, c, g, e]; <-- anything past this point won't work
所以基本上你检查自己,然后看看你的朋友是否是person2的朋友,然后看看他们的朋友是否是person2的朋友,如果他们然后添加到列表中。
虽然不确定如何执行此操作。
好的,所以我得到了类似于我需要的东西。
fb(X,X,_).
fb(X,Y,List) :-
friend(X,Y),
X \== Y,
List = [X,Y].
fb(X,Y,List) :-
friend(X,Z),friend(Z,Y),
X \== Y, X \== Z, Z \== Y,
List = [X,Z,Y].
fb(X,Y,List) :-
friend(X,Z),friend(Z,Q),friend(Q,Y),
X \== Y,X \== Z, X \== Q, Z \== Q, Z \== Y, Q \== Y,
List = [X,Z,Q,Y].
这似乎有效,但似乎我可以通过递归来浓缩这一点,只是不确定如何。
答案 0 :(得分:1)
我假设您已将friend(X,Y)
定义为f(X,Y)
或f(Y,X)
。
您的问题可以通过添加一个参数来递归解决,该参数指定允许的最大路径长度,并在每次递归调用之前递减。
fof(X,X,[X],_).
fof(X,Z,[X|Path],N) :-
N >= 1,
friend(X,Y),
M is N-1,
fof(Y,Z,Path,M),
\+ member(X,Path). % no duplicates
通过最大值找到朋友的朋友两个中间人,分三步:
?- fof(a,e,L,3).
L = [a, b, c, e] ;
L = [a, b, e] ;
L = [a, c, e] ;
L = [a, c, g, e] ;
L = [a, c, b, e] ;
false.
?- fof(a,z,L,3).
false.