我努力获得不错的结果,
我有一些朋友,
friend(a,b).
friend(a,b2).
friend(a,b3).
friend(b,c).
friend(c,d).
friend(d,e).
friend(e,f).
使用findall(X,friend(a,X),List)
我得到a
List=[b,b2,b3].
例如,我想获得a
的3级朋友列表,例如,我想要a
的直接朋友,a
朋友的朋友(这意味着) b
,b2
,b3
)的朋友和c
的朋友。获取清单:
List=[b,b2,b3,c,d].
我正在尝试一切。我只能得到直接的朋友或所有朋友的朋友。
帮助!!
答案 0 :(得分:3)
对于找到距离给定距离的朋友的谓词,正如您在评论中所要求的那样,您需要三个参数,即两个朋友和距离。让我们给它一个很好的关系名称,比如if float(computer_deck[0].weight) > float(user_deck[0].weight):
print("Computer wins.")
computer_deck.append(user_deck.pop(0))
else:
print("You win.")
user_deck.append(computer_deck.pop(0))
。现在让我们尝试描述这种关系:
friend_of_maxdist/3
这个谓词一个接一个地传递给定距离的所有朋友:
friend_of_maxdist(F1,F2,D) :-
D > 0, % if the distance is greater than 0
friend(F1,F2). % F2 is a friend in range
friend_of_maxdist(F1,F2,D) :-
D > 1, % if the distance is greater than 1
D0 is D-1,
friend(F1,X), % X is an intermediary friend
friend_of_maxdist(X,F2,D0). % of distance minus 1
现在您可以在列表中收集所有解决方案。我将使用bagof/3显示示例查询,请参阅下文,了解原因:
?- friend_of_maxdist(a,F2,1).
F2 = b ;
F2 = b2 ;
F2 = b3 ;
false.
?- friend_of_maxdist(a,F2,2).
F2 = b ;
F2 = b2 ;
F2 = b3 ;
F2 = c ;
false.
?- friend_of_maxdist(a,F2,3).
F2 = b ;
F2 = b2 ;
F2 = b3 ;
F2 = c ;
F2 = d ;
false.
但是,由于使用?- bagof(F2,friend_of_maxdist(a,F2,1),L).
L = [b, b2, b3].
?- bagof(F2,friend_of_maxdist(a,F2,2),L).
L = [b, b2, b3, c].
?- bagof(F2,friend_of_maxdist(a,F2,3),L).
L = [b, b2, b3, c, d].
和>/2
,is/2
如果第三个参数不是基数,则会产生错误,例如对于查询:
friend_of_maxdist/3
如果您不打算以这种方式使用谓词,那么您已经完成了。否则你可能想看看CLP(FD)。对上面的代码进行以下更改:
?- friend_of_maxdist(a,F2,N).
ERROR: >/2: Arguments are not sufficiently instantiated
如果您现在尝试有问题的查询,则会得到答案而不是错误。但是,您会在答案中获得剩余目标(有关详细信息,请参阅documentation):
:- use_module(library(clpfd)). % <- new
friend_of_maxdist(F1,F2,D) :-
D #> 0, % <- change
friend(F1,F2).
friend_of_maxdist(F1,F2,D) :-
D #> 1, % <- change
D0 #= D-1, % <- change
friend(F1,X),
friend_of_maxdist(X,F2,D0).
要获取实际数字而不是?- friend_of_maxdist(a,F2,N).
F2 = b,
N in 1..sup ;
F2 = b2,
N in 1..sup ;
F2 = b3,
N in 1..sup ;
F2 = c,
N in 2..sup,
_G778+1#=N,
_G778 in 1..sup ;
F2 = d,
N in 3..sup,
_G1264+1#=N,
_G1264 in 2..sup,
_G1288+1#=_G1264,
_G1288 in 1..sup ;
F2 = e,
N in 4..sup,
_G1855+1#=N,
_G1855 in 3..sup,
_G1879+1#=_G1855,
_G1879 in 2..sup,
_G1903+1#=_G1879,
_G1903 in 1..sup ;
F2 = f,
N in 4..sup,
_G2446+1#=N,
_G2446 in 4..sup,
_G2470+1#=_G2446,
_G2470 in 3..sup,
_G2494+1#=_G2470,
_G2494 in 2..sup,
_G2518+1#=_G2494,
_G2518 in 1..sup ;
false.
的范围,请限制其范围并标记它:
N
现在您可以收集上述解决方案:
?- N in 0..3, friend_of_maxdist(a,F2,N), label([N]).
N = 1,
F2 = b ;
N = 2,
F2 = b ;
N = 3,
F2 = b ;
N = 1,
F2 = b2 ;
N = 2,
F2 = b2 ;
N = 3,
F2 = b2 ;
N = 1,
F2 = b3 ;
N = 2,
F2 = b3 ;
N = 3,
F2 = b3 ;
N = 2,
F2 = c ;
N = 3,
F2 = c ;
N = 3,
F2 = d ;
false.
在上面的查询中,您可以看到我建议?- bagof(F2,(N in 0..3, friend_of_maxdist(a,F2,N), label([N])),L).
N = 1,
L = [b, b2, b3] ;
N = 2,
L = [b, b2, b3, c] ;
N = 3,
L = [b, b2, b3, c, d].
收集解决方案的原因:bagof/3
绑定到一个值,然后您获得与该值相关的所有解决方案。如果您使用N
尝试相同的操作,则可以在一个列表中获得三个列表中的所有元素:
findall/3
要使用?- findall(F2,(N in 0..3, friend_of_maxdist(a,F2,N), label([N])),L).
L = [b, b, b, b2, b2, b2, b3, b3, b3|...].
获得相同的解决方案,您必须明确告诉bagof/3
不要在目标中绑定bagof/3
:
N
请注意,谓词的CLP(FD) - 版本现在类似于真实关系,正如其关系名称所示。
答案 1 :(得分:0)
以下代表三级友谊。正如评论中所说,如果你想要更多,你可能想要寻找递归。
% my friend is my friend
friend_of_friend(X,Y):-
friend(X,Y).
% the friend of my friend is my friend
friend_of_friend(X,Y):-
friend(X,Z),
friend(Z,Y).
% the friend of the friend of my friend is my friend
friend_of_friend(X,Y):-
friend(X,A),
friend(A,B),
friend(B,Y).
然后
findall(X, friend_of_friend(a,X), List).
给出:
List = [b, b2, b3, c, d]
这代表无限的递归友谊:
recursive_friend(X,Y):-
friend(X,Y).
recursive_friend(X,Y):-
friend(X,Z),
recursive_friend(Z,Y).
并给予:
List = [b, b2, b3, c, d, e, f]