2017-04-11 201 views
1

这是我的代码:序言 - 添加从列表中的元素到另一个列表,不重复

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

什么它应该做的是检查,如果名称1或名称2已经在绑定列表,并将其添加到结果。

运行这个合法查询

students([ Dickens+Joyce+1, 
      Chekhov+Tolstoy+2, 
      Austen+Shakespeare+3, 
      Shirley+Byron+4 
     ], 
     StudentList). 

只是给了我假的。我应该如何调整我的编码?

回答

1

问题是你不能测试一个元素,例如Name1是否是Namelist中的成员,因为Namelist没有被实例化,这导致使用否定时出现问题。例如尝试:

?- member(a,L). 
L = [a|_G6809] . 

它成功假设L是一个| _G6809],所以部分实例化L,但现在尝试:

?- \+member(a,L). 
false. 

这不能做其他任何失败。您已经使用过很多次,如:not(not_member(Name2, NameList)),因为NameList没有实例化,所以会失败。

为了解决你需要另一个列表 - 蓄能器,你将存储所有的元素,你觉得它会在每一步中完全实例,所以你将能够检查元素是否是会员或不:

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, “契诃夫“+”Tolstoy“+2, ”Austen“+”Shakespeare“+3, ”Shirley“+”Byron“+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. 
相关问题