2017-04-11 166 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. 
相關問題