Prolog模拟社交圈

社交圈中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).

  

原文地址:https://www.cnblogs.com/hanani/p/9981213.html