我的部分工作存在问题。我应该编写一个谓词“友好”,当网络成员X被称为友好时,如果X喜欢回复所有喜欢他/她的人,那么这应该是真的。
编辑:在下面的例子中,巴里是友好的,因为喜欢巴里的人是卡拉和巴里喜欢卡拉的人。卡拉不是正确的答案,因为喜欢卡拉的人的名单是Barry,Clark和Oliver但是卡拉只喜欢巴里和克拉克,所以卡拉不友好。 例如G = [人(kara,[巴里,克拉克]),人(布鲁斯,[克拉克,奥利弗]),人(巴里,[卡拉,奥利弗]),人(克拉克,[奥利弗,卡拉] ),人(奥利弗,[卡拉])]到目前为止我所拥有的;
friendly(G, X):-
member_(person(X, _), G),
likers(G, X, L),
likes_all(G, X, L).
% to get the list of members who like X;
likers(G, X, [Y|T]) :-
likes(G, Y, X),
select_(Y, G, G2),
likers(G2, X, T).
likers([], _, []).
likers([], _, _).
likers(_, _, []).
% select is used to remove the person from the list once visited.
select_(X, [person(X, _)|T], T).
select_(X, [H|T], [H|R]) :-
select_(X, T, R).
% to check whether X likes all the list of people that like X;
likes_all(G, X, [H|T]):-
likes(G, X, H),
likes_all(G, X, T).
likes_all(_, _, []).
likes_all(G, [H|T], X):-
likes(G, H, X),
likes_all(G, T, X).
likes_all(_, [],_).
likes(G, X, Y):-
member_(person(X, L), G),
member_(Y, L).
member_(X, [X|_]).
member_(X, [_|T]) :-
member_(X, T).
我的问题是它无法正常工作。请参阅下面的示例输出。
所以,我不知道出了什么问题以及我该怎么做。我们不允许使用任何内置的谓词或控制操作符,所以没有!,;,=,\ =,+等,只有纯粹的序言。
赞赏前进的任何暗示。
输出:
[debug] ?- friendly([person(kara, [barry, clark]),person(bruce, [clark, oliver]),person(barry, [kara, oliver]),person(clark, [oliver, kara]),person(oliver, [kara])], X).
X = kara ;
X = kara ;
X = kara ;
X = kara ;
X = kara ;
X = bruce ;
X = barry ;
X = barry ;
X = clark ;
X = clark ;
X = oliver ;
false.
我认为我的错误在喜欢的功能中。 “喜欢者”的输出:
?- likers([person(kara, [barry, clark]), person(bruce, [clark, oliver]), person(barry, [kara, oliver]), person(clark, [oliver, kara]), person(oliver, [kara])], kara, L).
L = [] ;
L = [barry] ;
L = [barry, clark] ;
L = [barry, clark, oliver] ;
L = [barry, oliver] ;
L = [barry, oliver, clark] ;
L = [clark] ;
L = [clark, barry] ;
L = [clark, barry, oliver] ;
L = [clark, oliver] ;
L = [clark, oliver, barry] ;
L = [oliver] ;
L = [oliver, barry] ;
L = [oliver, barry, clark] ;
L = [oliver, clark] ;
L = [oliver, clark, barry] ;
false.
在上面,正确的答案是L = [barry,clark,oliver]或其中一个组合。有没有办法在纯粹的序言中得到它?
答案 0 :(得分:1)
以下是您的程序应该如何编写:
person(kara,[barry, clark]).
person(bruce,[clark,oliver]).
person(barry,[kara,oliver]).
person(clark,[oliver,kara]).
person(oliver,[kara]).
likes_back([],_).
likes_back([Y|Ys],X) :-
person(Y,Xs),
member(X,Xs),
likes_back(Ys,X).
friendly(X) :-
person(X,Ys),
likes_back(Ys,X).
?- friendly(X),write(X),nl,fail.
当我运行它时,我只得到kara
- 根据我对您提供的数据和规则的检查,这是正确的。
答案 1 :(得分:1)
在平静下来之后,以及一些谷歌,这是一个应该令人满意的答案。关键的想法是不仅要传递我们感兴趣的人X
,还要传递补集(AEX
)。与此相比,相当于否定与X
进行比较。
friendly(X) :-
G = [person(kara,[barry,clark]),
person(bruce,[clark,oliver]),
person(barry,[kara,oliver]),
person(clark,[oliver,kara]),
person(oliver,[kara])],
allppl(G,All),
mymember(person(X,Xs),G),
select(X,All,AEX),
likers(G,X,AEX,[],Fs),
subset(Fs,Xs).
获取所有人的列表:
allppl([person(P,_)|Rest],[P|Ps]) :-
allppl(Rest,Ps).
allppl([],[]).
这是我的旧likers/4
加上补充集。
likers([person(Y,Ys)|Rest],X,AEX,Fs0,Fs) :-
mymember(X,Ys),
likers(Rest,X,AEX,[Y|Fs0],Fs).
likers([person(_,Ys)|Rest],X,AEX,Fs0,Fs) :-
subset(Ys,AEX),
likers(Rest,X,AEX,Fs0,Fs).
likers([],_,_,Fs,Fs).
这里有一些辅助谓词。
select(X,[X|Xs],Xs).
select(X,[Y|Xs],[Y|Zs]) :-
select(X,Xs,Zs).
subset([],_).
subset([X|Xs],Ys) :-
mymember(X,Ys), subset(Xs,Ys).
mymember(X,[X|_]).
mymember(X,[_|Xs]) :-
mymember(X,Xs).
现在我
?- friendly(X).
X = bruce ? ;
X = barry ? ;
no
答案 2 :(得分:0)
好的,如果我理解正确的话,这是一个解决方案。我认为没有人喜欢的人(布鲁斯)不被认为是友善的。
friendly(P) :-
person_likes(P,Ps),
findall(X,(person_likes(X,Zs),member(P,Zs)),Fs), Fs \= [],
check_subset(Fs,Ps).
check_subset([X|Xs],Set) :-
memberchk(X,Set),
check_subset(Xs,Set).
check_subset([],_).
person_likes(kara,[barry,clark]).
person_likes(bruce,[clark,oliver]).
person_likes(barry,[kara,oliver]).
person_likes(clark,[oliver,kara]).
person_likes(oliver,[kara]).
结果:
?- friendly(X).
X = barry ? ;
no
如果您不被允许使用findall/3
,那么您需要自己编写另外三行代码。
答案 3 :(得分:0)
您可以这样写likers/4
:
likers([person(Y,Ys)|Rest],X,Fs0,Fs) :-
( memberchk(X,Ys) ->
Fs1 = [Y|Fs0]
; Fs1 = Fs0 ),
likers(Rest,X,Fs1,Fs).
likers([],_,Fs,Fs).
用第三个参数空列表调用它。
增加:不带分号:
likers([person(Y,Ys)|Rest],X,Fs0,Fs) :-
memberchk(X,Ys),
likers(Rest,X,[Y|Fs0],Fs).
likers([person(_,Ys)|Rest],X,Fs0,Fs) :-
\+ memberchk(X,Ys),
likers(Rest,X,Fs0,Fs).
likers([],_,Fs,Fs).