Prolog GNU - 有一个困难的时间,列表和递归

时间:2010-10-24 15:10:23

标签: list recursion prolog

所以,我仍然不完全理解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].

这似乎有效,但似乎我可以通过递归来浓缩这一点,只是不确定如何。

1 个答案:

答案 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.