社交圈中like是单向的,你like的人没有义务like回来你。。。
这个实现关键难题是,不采用No逻辑,完全使用正逻辑来实现like, dislike等:
(cnblog也没有Prolog, 依旧使用Scale代替,汗。。)
/* Likes */ /* */ likes(G,X,Y):- member1(person(X,Xs),G), member1(Y,Xs). /* member */ member1(X,[X|_]). member1(X,[_|Ys]):- member1(X,Ys). member2(X,G):- member1(person(X,_),G). notmember(_,_,[]). notmember(G,X,[Y|Ys]):- notmember(G,X,Ys), different(G,X,Y). /*remove from list*/ remove1(X, [X|Xs], Xs). remove1(X, [H|Xs], [H|Ys]) :- remove1(X, Xs, Ys). /*different*/ different(G,X,Y):- member2(X,G), remove1(person(X, _), G, Res), member2(Y,Res). /* dislikes */ /* */ dislikes(G,X,Y):- different(G,X,Y), likes(G,Y,X), member1(person(X,Xs),G), notmember(G,Y,Xs). /*popular*/ popular(G,X):- member1(person(X,Xfriendlist),G), alllikes(X,Xfriendlist,G). /* all elements in [X|Xs] likes Y */ alllikes(Y,[X|Xs],G):- likes(G,X,Y), alllikes(Y,Xs,G). alllikes(_,[],_). /*outcast*/ outcast(G,X):- member1(person(X,Xfriendlist),G), alldislikes(X,Xfriendlist,G). /* all elements in [X|Xs] dislikes Y */ alldislikes(Y,[X|Xs],G):- dislikes(G,X,Y), alldislikes(Y,Xs,G). alldislikes(_,[],_). /*friendly*/ friendly(G,X):- remove1(person(X, _), G, Gg), wholikes(G,person(X,_),Gg,[],Res), likesall(G,X,Res). /*wholikes*/ wholikes(_,_,[],Cont,Cont). wholikes(G,person(X,_),[person(Y,_)|YYs],Cont,Res):- likes(G,Y,X), wholikes(G,person(X,_),YYs,[Y|Cont],Res). wholikes(G,person(X,_),[person(_,Ys)|YYs],Cont,Res):- notmember(G,X,Ys), wholikes(G,person(X,_),YYs,Cont,Res). /*likesall*/ likesall(_,_,[]). likesall(G,X,[Y|Ys]):- likes(G,X,Y), likesall(G,X,Ys). /*dislikesall*/ dislikesall(_,_,[]). dislikesall(G,X,[Y|Ys]):- dislikes(G,X,Y), dislikesall(G,X,Ys). /*hostile*/ hostile(G,X):- remove1(person(X, _), G, Gg), wholikes(G,person(X,_),Gg,[],Res), dislikesall(G,X,Res). /*admires*/ admires(G,X,Y):- likes(G,X,Y), different(G,X,Y). admires(G,X,Y):- likes(G,X,Z), remove1(person(X,_),G,Res), admires(Res,Z,Y). notEmpty([_|_]). isEmpty([]). checkEvery(_,_,[],Res1,Res1). checkEvery(G,Xs,[Y|Ys],Res1,Res2):- member1(Y,Xs), checkEvery(G,Xs,Ys,Res1,Res2). checkEvery(G,Xs,[Y|Ys],Res1,Res2):- notmember(G,Y,Xs), checkEvery(G,Xs,Ys,[Y|Res1],Res2). checkGraph(G,X,_,[],[],[]):- member1(person(X,[]),G). checkGraph(G,_,_,Lis1,Lis2,Lis1):- notEmpty(Lis1), checkEvery(G,Lis1,Lis2,[],Res), isEmpty(Res). checkGraph(G,_,Y,Lis1,Lis2,Res):- notEmpty(Lis1), checkEvery(G,Lis1,Lis2,[],Res1), notEmpty(Res1), member1(Z,Res1), member1(person(Z,Zs),G), checkToAdd(G,Zs,Lis2,Cont), checkGraph(G,Z,Y,[Z|Lis1],Cont,Res). checkGraph(G,X,Y,Lis1,Lis2,Res):- isEmpty(Lis1), member1(person(X,Xs),G), checkToAdd(G,Xs,Lis2,Cont), member1(Z,Xs), notmember(G,Z,Lis1), checkGraph(G,Z,Y,[X|Lis1],Cont,Res). checkToAdd(_,[],Lis,Lis). checkToAdd(G,[X|Xs],Lis,Res):- member1(X,Lis), checkToAdd(G,Xs,Lis,Res). checkToAdd(G,[X|Xs],Lis,Res):- member1(person(X,_),G), notmember(G,X,Lis), checkToAdd(G,Xs,[X|Lis],Res). notMemOf(G,X,Y):- checkGraph(G,X,Y,[],[],Res), notmember(G,Y,Res). /*indifferent*/ indifferent(G,X,Y):- different(G,X,Y), notMemOf(G,X,Y). /* Same world */ compareLabel([X|Xss],Ys,Label):- member1((X,Xs),Label), member1(Xs,Ys), remove1(Xs,Ys,Yss), compareLabel(Xss,Yss,Label). compareLabel([],[],_). compareFriends(G,H,X,Label):- member1(person(X,Xs),G), member1((X,Y),Label), member1(person(Y,Ys),H), compareLabel(Xs,Ys,Label). allFriends(G,H,[X|Xs],Label):- compareFriends(G,H,X,Label), allFriends(G,H,Xs,Label). allFriends(_,_,[],_). same(G,H,A):- getPerson(G,X), getPerson(H,Y), combine(X,Y,A). combine([],[],[]). combine([X|Xs],Ys,[H|T]):- member1(Y,Ys),pair(H,X,Y), remove1(Y,Ys,P), combine(Xs,P,T). pair((X,Y),X,Y). getPerson([],[]). getPerson([person(X,_)|Ys],[X|Xs]):-getPerson(Ys,Xs). same_world(G,H,Label):- getPerson(G,P), same(G,H,Label), allFriends(G,H,P,Label).