创建列表,搜索已经给出的内容并在prolog上进行组合

时间:2011-05-12 23:36:22

标签: prolog

我想制作一个Prolog程序。 谓词将是这样的:

name(name, failedCourse, age)

该计划的数据库是:

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

我想实现谓词nameList(A, 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

descend(X,Y,A) :- name(X,Y,A).
descend(X,Y,A) :- name(X,Z,A),descend(Z,Y,A).
findall(director(X),descend(Y,X),Z).
?- findall(B,descend(B,X,Y),A). returns A = [george, steve, jane].

但我无法弄明白在谓词中使用列表A :(我无法在A中搜索nameList列表。

如果你帮助我,我将非常感激。

2 个答案:

答案 0 :(得分:0)


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

答案 1 :(得分:0)

您需要的主要内容是计算给定长度和给定列表的组合的谓词:

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.

(查看更多here。)

现在您可以将此谓词应用于您的数据:

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.