在prolog上创建列表、搜索给定的内容并进行组合

在prolog上创建列表、搜索给定的内容并进行组合,prolog,Prolog,我想做一个Prolog程序。 谓词将如下所示: name(name, failedCourse, age) 该计划的数据库为: name(george, math, 20). name(steve, phys, 21). name(jane, chem, 22). 我想实现谓词nameListA,B。A表示名称列表,B表示列表中的名称数量。例如: nameList([george, steve],2). returns true nameList([george, steve],X). re

我想做一个Prolog程序。 谓词将如下所示:

name(name, failedCourse, age)
该计划的数据库为:

name(george, math, 20).
name(steve, phys, 21).
name(jane, chem, 22).
我想实现谓词nameListA,B。A表示名称列表,B表示列表中的名称数量。例如:

nameList([george, steve],2). returns true
nameList([george, steve],X). returns X=2
nameList(X,2). returns X=[george, steve]; X=[george, jane]; X=[steve, jane]
nameList([martin],1). returns false (because martin is not included database.)
我想列一个包含数据库中所有名字的列表。因为这个原因,我做了一个findall

但我无法在谓词中使用列表A:我无法在列表中搜索名称列表中的A


如果您能帮助我,我将不胜感激。

您需要的主要是一个谓词,用于计算给定长度和给定列表的组合:


name(george, math, 20).
name(steve, phys, 21).
name(jane, chem, 22).

name_list(Name_List,N) :-
        integer(N),
        findall(Name,name(Name,_,_),L),
        combination(L,N,Name_List).
name_list(Name_List,N) :-
        var(N),
        findall(Name,name(Name,_,_),L),
        length(L,Len),
        for(1,N,Len),
        combination(L,N,Name_List).

combination(X,1,[A]) :-
        member(A,X).
combination([A|Y],N,[A|X]) :-
        N > 1,
        M is N - 1,
        combination(Y,M,X).
combination([_|Y],N,A) :-
        N > 1,
        combination(Y,N,A).
comb(0, _, []).

comb(N, [X | T], [X | Comb]) :-
    N > 0,
    N1 is N - 1,
    comb(N1, T, Comb).

comb(N, [_ | T], Comb) :-
    N > 0,
    comb(N, T, Comb).
用法:

?- comb(2, [a, b, a], Comb).
Comb = [a, b] ;
Comb = [a, a] ;
Comb = [b, a] ;
false.
看更多

现在,您可以对数据应用此谓词:

name(george, math, 20).
name(steve, phys, 21).
name(jane, chem, 22).    

name_list(L, N) :-
    findall(X, name(X, _, _), Xs),
    length(Xs, Len),
    between(0, Len, N),
    comb(N, Xs, L).
用法示例:

?- name_list(L, N).
L = [],
N = 0 ;
L = [george],
N = 1 ;
L = [steve],
N = 1 ;
L = [jane],
N = 1 ;
L = [george, steve],
N = 2 ;
L = [george, jane],
N = 2 ;
L = [steve, jane],
N = 2 ;
L = [george, steve, jane],
N = 3 ;
false.

?- name_list([george, steve], N).
N = 2 ;
false.

?- name_list(L, 2).
L = [george, steve] ;
L = [george, jane] ;
L = [steve, jane] ;
false.

要获得所有名称,只需调用:findallX、nameX、u、ux、Xs,即不需要下降和导演。谢谢。我想我必须写序言。但我不能再做另一件事了。如果你能帮助我,我会非常高兴:@dark如果你喜欢这个答案,请投票,如果你认为它能回答你的问题:将它标记为选中的答案,如果你还有其他问题,请在那里创建一个新的帖子。这就是Stackoverflow的工作原理。。。
?- name_list(L, N).
L = [],
N = 0 ;
L = [george],
N = 1 ;
L = [steve],
N = 1 ;
L = [jane],
N = 1 ;
L = [george, steve],
N = 2 ;
L = [george, jane],
N = 2 ;
L = [steve, jane],
N = 2 ;
L = [george, steve, jane],
N = 3 ;
false.

?- name_list([george, steve], N).
N = 2 ;
false.

?- name_list(L, 2).
L = [george, steve] ;
L = [george, jane] ;
L = [steve, jane] ;
false.