2012-12-17 75 views
1

我有這兩個程序,他們不工作,因爲他們應該。第一個without_doubles_2(Xs,Ys)應該表明,如果Ys是X中出現的沒有重複的元素的列表,那麼它是對的。 Y中的元素與X的順序相反,保留了第一個重複值。例如,without_doubles_2([1,2,3,4,5,6,4,4],X)打印X = [6,5,4,3,2,1],但它打印爲false。Prolog程序 - 如何使它工作?

without_doubles_2([],[]). 
without_doubles_2([H|T],[H|Y]):- member(H,T),!, 
           delete(H,T,T1), 
           without_doubles_2(T1,Y). 

without_doubles_2([H|T],[H|Y]):- without_doubles_2(T,Y). 

reverse([],[]). 
reverse([H|T],Y):- reverse(T,T1), addtoend(H,T1,Y). 

addtoend(H,[],[H]). 
addtoend(X,[H|T],[H|T1]):-addtoend(X,T,T1). 


without_doubles_21(X,Z):- without_doubles_2(X,Y), 
          reverse(Y,Z). 

第二個是我該如何讓這個程序使用一個字符串?它應該從字符串中刪除元音並僅打印輔音。

deleteV([H|T],R):-member(H,[a,e,i,o,u]),deleteV(T,R),!. 
deleteV([H|T],[H|R]):-deleteV(T,R),!. 
deleteV([],[]). 

回答

2

因爲你的論點錯誤的順序您對delete調用總是失敗:

delete(+List1, @Elem, -List2) 

所以不是

delete(H, T, T1) 

你想

delete(T, H, T1) 

尋找一個像這樣的錯誤是簡單地使用swi-prolog解釋器的跟蹤功能 - 只需輸入trace.即可開始跟蹤模式,輸入謂詞並查看解釋器在做什麼。在這種情況下,您會看到失敗來自delete聲明。 The documentation related to tracing can be found here

另請注意,您可以重寫謂詞,省略成員檢查並因此刪除第三個子句,因爲delete([1,2,3],9001,[1,2,3])的計算結果爲true - 如果元素不在列表中,則結果與輸入相同。所以,你的斷言看起來是這樣的(名字,由於縮短爲lazyness):

nodubs([], []). 
nodubs([H|T], [H|Y]) :- delete(T, H, T1), nodubs(T1, Y). 

關於第二個問題,你可以使用string_to_list謂詞把字符串轉換成字符(表示爲ASCII碼)的列表。

至於謂詞從字符串中刪除vovels,我會實現它是這樣的(有可能是這個問題,或者你可以使用一些內置的插件更好的解決方案,但我的序言是有點生鏽):

%deleteall(+L, +Elems, -R) 
%a helper predicate for deleting all items in Elems from L 
deleteall(L, [], L). 
deleteall(L, [H|T], R) :- delete(L, H, L1), deleteall(L1, T, R). 

deleteV(S, R) :- 
    string_to_list(S, L),   %create list L from input string 
    string_to_list("aeiou", A), %create a list of all vovels 
    deleteall(L, A, RL),   %use deleteall to delete all vovels from L 
    string_to_list(R, RL).  %turn the result back into a string 
0

deleteV/2可以利用庫(lists):

?- subtract("carlo","aeiou",L), format('~s',[L]). 
crl 
L = [99, 114, 108]. 

,同時刪除重複,我們可能需要從sort/2和select/3的優勢:

nodup(L, N) :- 
    sort(L, S), 
    nodup(L, S, N). 

nodup([], _S, []). 
nodup([X|Xs], S, N) :- 
    (select(X, S, R) -> N = [X|Ys] ; N = Ys, R = S), 
    nodup(Xs, R, Ys). 

測試:

?- nodup([1,2,3,4,4,4,5,2,7],L). 
L = [1, 2, 3, 4, 5, 7]. 

編輯要好得多,從ssBarBee

?- setof(X,member(X,[1,2,2,5,3,2]),L). 
L = [1, 2, 3, 5]. 
+0

添加SETOF爲替代去除雙打。 – ssBarBee