在列表中搜索名称-Sicstus Prolog

在列表中搜索名称-Sicstus Prolog,prolog,Prolog,我最近开始胡闹Prolog,但在列表方面遇到了绊脚石 假设我有一个列表[dom,is,a,man,jane,is,a,woman,mary,is,a,woman],我想创建一个新的女性名字列表[jane,mary]。我该怎么做呢?我想我必须在列表中搜索后面跟is,a,woman的任何X,但我不知道如何实现这一点。我在谷歌上搜索了好几个小时都没有用。如果我有:s,我会发布代码 谢谢你的帮助 % end once the input is empty find_gender([], _, []).

我最近开始胡闹Prolog,但在列表方面遇到了绊脚石

假设我有一个列表[dom,is,a,man,jane,is,a,woman,mary,is,a,woman],我想创建一个新的女性名字列表[jane,mary]。我该怎么做呢?我想我必须在列表中搜索后面跟is,a,woman的任何X,但我不知道如何实现这一点。我在谷歌上搜索了好几个小时都没有用。如果我有:s,我会发布代码

谢谢你的帮助

% end once the input is empty
find_gender([], _, []).

% Compare the first 4 "entries" in the list.
% Name and Gender are variables, b/c they are written in upper case.
% 'is' and 'a' are atom.
% If the pattern matches, prepend the Name to the results.
find_gender([Name,is,a,Gender|Tail], Gender, [Name|Names]) :-
    % Find further Names in the Tail of the input list.
    find_gender(Tail, Gender, Names).

% The person is not of that Gender.
% You don't need to catch the Name here, b/c it won't be used. 
find_gender([_,is,a,X|Tail], Gender, Names) :-
    X \= Gender, % otherwise you would have wrong results when backtracking
    find_gender(Tail, Gender, Names).

% This is your usage example:
find_women(List, Names) :-
    find_gender(List, woman, Names).
find_men(List, Names) :-
    find_gender(List, man, Names).
反之亦然:

?- find_women(List, [jane,marry]).
List = [jane, is, a, woman, marry, is, a, woman] ;
false.
如果您的输入列表可能包含其他数据,如[jane,owns,a,car,jane,is,a,Women,the,car,is,red],那么您可以通过添加以下子句删除条目,直到再次找到您的模式:

find_gender([_|T], Gender, Names) :-
    find_gender(T, Gender, Names).

但这将导致回溯时产生多个结果,并忽略一些名称。你可能想引入削减!在这种情况下的第一个条款中,

总是在描述列表时,考虑使用DCGS。例如:

men_women([], [])     --> [].
men_women(Ms, [W|Ws]) --> [W,is,a,woman], men_women(Ms, Ws).
men_women([M|Ms], Ws) --> [M,is,a,man], men_women(Ms, Ws).
示例查询及其结果:

?- phrase(men_women(_, Ws), [dom,is,a,man,jane,is,a,woman,mary,is,a,woman]).
Ws = [jane, mary] ;
false.
此DCG还适用于非常一般的查询,例如:

?- length(Ls, _), phrase(men_women(_, Ws), Ls).
Ls = [], Ws = [] ;
Ls = [_G376, is, a, woman], Ws = [_G376] ;
Ls = [_G376, is, a, man], Ws = [] ;
Ls = [_G376, is, a, woman, _G388, is, a, woman], Ws = [_G376, _G388] .

你考虑的是哪种算法,用声明的方式?因为,你知道,对我们来说,重要的是确保我们的答案不会妨碍你思考你的课堂作业……我认为,反复阅读一系列事实更容易理解,例如[womanmary,mandom,womanjane],这样谓词就意味着mary是个女人。这张单子是一个限制吗?在谷歌上搜索几个小时来寻找答案,而不学习语言,也不花时间尝试一些事情,这不是学习的最佳途径。这并不是一个非常优雅的场景,但如果你继续往下看,你不会在列表中搜索像是,一个,女人之类的东西,这是一个必要的方式来看待它。如果您的列表结构真的那么严格,您可以使用[X,is,a,woman | T]等模式从列表前面选择一位女性,然后在T上递归。谢谢您的建议。顺便说一句,这不是课堂作业,我只是想学习序言:哇,我以前从未见过DCG。谢谢你,马特!这看起来很棒,可能需要一段时间才能完全理解。谢谢你的回答。我一直在研究它,并试图理解它。以您为例,尝试一个可能包含额外数据的列表,例如[jane,owns,a,car,jane,is,a,woman,the,car,is,red]似乎不起作用。即使你添加了最后一条。开场白说不!想不出来,有什么想法吗?谢谢=对不起,我忘记了性别参数。现在修好了。