这是我的代码:
students([], NameList).
students([Name1+Name2+_|MoreProjects], [Name1,Name2|NameList]) :-
not_member(Name1, NameList),
not_member(Name2, NameList),
students(MoreProjects, NameList).
students([Name1+Name2+_|MoreProjects], [Name1|NameList]) :-
not_member(Name1, NameList),
not(not_member(Name2, NameList)),
students(MoreProjects, NameList).
students([Name1+Name2+_|MoreProjects], [Name2|NameList]) :-
not(not_member(Name1, NameList)),
not_member(Name2, NameList),
students(MoreProjects, NameList).
students([Name1+Name2+_|MoreProjects], NameList) :-
not(not_member(Name1, NameList)),
not(not_member(Name2, NameList)),
students(MoreProjects, NameList).
not_member(_, []).
not_member(X, [Head|Tail]) :-
X \= Head,
not_member(X, Tail).
它应该做的是检查Name1或Name2是否已经在未绑定列表中,并将其添加到结果中。
运行此合法查询
students([ Dickens+Joyce+1,
Chekhov+Tolstoy+2,
Austen+Shakespeare+3,
Shirley+Byron+4
],
StudentList).
只是给我假。我该如何调整编码?
答案 0 :(得分:1)
问题在于你无法测试Name1之类的元素是否是Namelist中的成员,因为Namelist没有实例化,这在使用否定时会导致问题。例如,尝试:
?- member(a,L).
L = [a|_G6809] .
成功假设L是[a | _G6809],所以它部分实例化L,但现在尝试:
?- \+member(a,L).
false.
这不能做任何失败的事情。您已经多次使用过这样的:not(not_member(Name2, NameList))
,因为NameList没有实例化,所以会失败,因为上面的例子。
为了修复你需要另一个List-accumulator你将存储你找到的所有元素,并且它将在每一步完全实例化,这样你就可以检查一个元素是否是成员:
students(L1,L2):-students(L1,L2,[]).
students([], L, L).
students([Name1+Name2+_|MoreProjects], NameList, L):-
not_member(Name1, L),
not_member(Name2, L),
students(MoreProjects, NameList,[Name1,Name2|L]).
students([Name1+Name2+_|MoreProjects], NameList, L):-
not_member(Name1, L),
not(not_member(Name2, L)),
students(MoreProjects, NameList, [Name1|L]).
students([Name1+Name2+_|MoreProjects], NameList, L):-
not(not_member(Name1, L)),
not_member(Name2, L),
students(MoreProjects, NameList, [Name2|L]).
students([Name1+Name2+_|MoreProjects], NameList, L):-
not(not_member(Name1, L)),
not(not_member(Name2, L)),
students(MoreProjects, NameList, L).
not_member(_, []).
not_member(X, [Head|Tail]) :-
X \= Head,
not_member(X, Tail).
在上面我们开始在必要时给第三个参数作为空列表添加元素。
此外,当您尝试查询时
students([ Dickens+Joyce+1,
Chekhov+Tolstoy+2,
Austen+Shakespeare+3,
Shirley+Byron+4
],
StudentList).
请注意,无论以大写字母开头的是Prolog中的变量,您都需要查询: 学生([“狄更斯”+“乔伊斯”+1, “契诃夫” + “托尔斯泰” +2, “奥斯汀” + “莎士比亚” +3, “雪莉” +“拜伦” +4 ] StudentList)。 现在让我们试试吧:
students([ "Dickens"+"Joyce"+1,"Chekhov"+"Tolstoy"+2, "Auste"+"Shakespeare"+3,"Shirley"+"Byron"+4 ], StudentList).
StudentList = ["Shirley", "Byron", "Auste", "Shakespeare", "Chekhov", "Tolstoy", "Dickens", "Joyce"] ;
false.
?- students([ "Dickens"+"Joyce"+1,"Byron"+"Tolstoy"+2, "Byron"+"Shakespeare"+3,"Byron"+"Byron"+4 ], StudentList).
StudentList = ["Shakespeare", "Byron", "Tolstoy", "Dickens", "Joyce"] ;
false.