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).