Prolog:获取错误而不是列表
Prolog: geting false instead of a list
我的知识库是这样的
user (USERID, USERNAME, [Tags])
例如
no(1,ana,[natureza,pintura,musica,sw,porto]).
no(11,antonio,[natureza,pintura,carros,futebol,lisboa]).
no(12,beatriz,[natureza,musica,carros,porto,moda]).
no(13,carlos,[natureza,musica,sw,futebol,coimbra]).
我正在尝试让用户与某个用户有 X 个共同标签
我有这段代码,但它 returns 错误而不是列表
有人能帮帮我吗?
uc(USER, X, L) :-
findall(N, no(N,_,_), Ns),
intersectioUserList(USER,Ns,X,L).
%
intersectioUserList(_, [], _, _).
intersectioUserList(USER, [H|T], X, L):-
intersectioUserList(USER, T, X, L),
intersectionUser(USER,H,X,L).
%
intersectionUser(USER,Y,X,L):-
no(USER,_,L1),
no(Y,_,L2),
intersection(L1,L2,L3),
list_length(L3,T),
((T >= X) -> append([Y],L,L)).
%
list_length([] , 0 ).
list_length([_|Xs] , L ) :- list_length(Xs,N) , L is N+1 .
%
感谢您的宝贵时间
我认为您不需要计算两个列表的交集,只需查看所需的标签是否出现在两个列表中即可(使用 member/2)。
uc(Uid1, Tag, Users) :-
no(Uid1, _, Tags1),
member(Tag, Tags1),
dif(Uid1, Uid2),
findall(Uid2, (no(Uid2, _, Tags2), member(Tag, Tags2)), Users).
no( 1, ana, [natureza, pintura, musica, sw, porto]).
no(11, antonio,[natureza, pintura, carros, futebol, lisboa]).
no(12, beatriz,[natureza, musica, carros, porto, moda]).
no(13, carlos, [natureza, musica, sw, futebol, coimbra]).
示例:
?- uc(1, natureza, Users).
Users = [11, 12, 13] ;
false.
?- uc(User, Tag, Users).
User = 1,
Tag = natureza,
Users = [11, 12, 13] ;
User = 1,
Tag = pintura,
Users = [11] ;
User = 1,
Tag = musica,
Users = [12, 13] ;
User = 1,
Tag = sw,
Users = [13]
...
true
编辑
获取列表 Users 与给定用户具有至少 MinNumberOfTags 个标签的用户 Uid1 你需要 intersection/3:
% uc(+Uid1, +MinNumberOfTags, -Users)
uc(Uid1, MinNumberOfTags, Users) :-
no(Uid1, _, Tags1),
dif(Uid1, Uid2),
findall( Uid2,
( no(Uid2, _, Tags2),
intersection(Tags1, Tags2, CommonTags),
length(CommonTags, N),
N >= MinNumberOfTags ),
Users ).
示例:
?- uc(11, 1, Users).
Users = [1, 12, 13].
?- uc(1, 1, Users).
Users = [11, 12, 13].
注意
SWI-Prolog 将谓词 intersection/3
定义为:
intersection([], _, []) :- !.
intersection([X|T], L, Intersect) :-
memberchk(X, L),
!,
Intersect = [X|R],
intersection(T, L, R).
intersection([_|T], L, R) :-
intersection(T, L, R).
我的知识库是这样的
user (USERID, USERNAME, [Tags])
例如
no(1,ana,[natureza,pintura,musica,sw,porto]).
no(11,antonio,[natureza,pintura,carros,futebol,lisboa]).
no(12,beatriz,[natureza,musica,carros,porto,moda]).
no(13,carlos,[natureza,musica,sw,futebol,coimbra]).
我正在尝试让用户与某个用户有 X 个共同标签
我有这段代码,但它 returns 错误而不是列表
有人能帮帮我吗?
uc(USER, X, L) :-
findall(N, no(N,_,_), Ns),
intersectioUserList(USER,Ns,X,L).
%
intersectioUserList(_, [], _, _).
intersectioUserList(USER, [H|T], X, L):-
intersectioUserList(USER, T, X, L),
intersectionUser(USER,H,X,L).
%
intersectionUser(USER,Y,X,L):-
no(USER,_,L1),
no(Y,_,L2),
intersection(L1,L2,L3),
list_length(L3,T),
((T >= X) -> append([Y],L,L)).
%
list_length([] , 0 ).
list_length([_|Xs] , L ) :- list_length(Xs,N) , L is N+1 .
%
感谢您的宝贵时间
我认为您不需要计算两个列表的交集,只需查看所需的标签是否出现在两个列表中即可(使用 member/2)。
uc(Uid1, Tag, Users) :-
no(Uid1, _, Tags1),
member(Tag, Tags1),
dif(Uid1, Uid2),
findall(Uid2, (no(Uid2, _, Tags2), member(Tag, Tags2)), Users).
no( 1, ana, [natureza, pintura, musica, sw, porto]).
no(11, antonio,[natureza, pintura, carros, futebol, lisboa]).
no(12, beatriz,[natureza, musica, carros, porto, moda]).
no(13, carlos, [natureza, musica, sw, futebol, coimbra]).
示例:
?- uc(1, natureza, Users).
Users = [11, 12, 13] ;
false.
?- uc(User, Tag, Users).
User = 1,
Tag = natureza,
Users = [11, 12, 13] ;
User = 1,
Tag = pintura,
Users = [11] ;
User = 1,
Tag = musica,
Users = [12, 13] ;
User = 1,
Tag = sw,
Users = [13]
...
true
编辑
获取列表 Users 与给定用户具有至少 MinNumberOfTags 个标签的用户 Uid1 你需要 intersection/3:
% uc(+Uid1, +MinNumberOfTags, -Users)
uc(Uid1, MinNumberOfTags, Users) :-
no(Uid1, _, Tags1),
dif(Uid1, Uid2),
findall( Uid2,
( no(Uid2, _, Tags2),
intersection(Tags1, Tags2, CommonTags),
length(CommonTags, N),
N >= MinNumberOfTags ),
Users ).
示例:
?- uc(11, 1, Users).
Users = [1, 12, 13].
?- uc(1, 1, Users).
Users = [11, 12, 13].
注意
SWI-Prolog 将谓词 intersection/3
定义为:
intersection([], _, []) :- !.
intersection([X|T], L, Intersect) :-
memberchk(X, L),
!,
Intersect = [X|R],
intersection(T, L, R).
intersection([_|T], L, R) :-
intersection(T, L, R).