2012-04-19 77 views
0

我是新來的Prolog和我被困在一個謂詞,我試圖做。其目的是通過給定P的四元組[X,Y,S,P]遞歸列表,當四元組具有相同的P時,它將其存儲在臨時列表中。當遇到新的P時,它會查看臨時列表是否大於長度2,如果是,則將臨時列表存儲在輸出列表中,如果小於2則刪除四元組,然後再次啓動遞歸新P.
繼承人我的代碼:序言:臨時列表存儲

deleteUP(_,[],[],[]). 
    deleteUP(P,[[X,Y,S,P]|Rest],Temp,Output):- 
     !, 
     appends([X,Y,S,P],Temp,Temp), 
     deleteUP(P,[Rest],Temp,Output). 

deleteUP(NextP,[[X,Y,S,P]|Rest],Temp,Output):- 
     NextP =\= P, 
     listlen(Temp,Z), 
     Z > 1, !, 
     appends(Temp,Output,Output), 
     deleteUP(NextP,[_|Rest],Temp,Output). 

listlen([], 0). 
listlen([_|T],N) :- 
     listlen(T,N1), 
     N is N1 + 1. 

appends([],L,L). 
appends([H|T],L,[H|Result]):- 
     appends(T,L,Result). 

感謝您的幫助!

回答

0

序列變量不能被'修改',因爲你試圖調用append:你需要一個新的變量來放置結果。注意:此代碼是未經測試...有關存儲,遞歸和啓動

deleteUP(_,[],[],[]). 

deleteUP(P,[[X,Y,S,P]|Rest],Temp,Output):- 
     !, 
     appends([X,Y,S,P],Temp,Temp1), 
     deleteUP(P, Rest, Temp1,Output). % was deleteUP(P,[Rest],Temp,Output). 

deleteUP(NextP,[[X,Y,S,P]|Rest],Temp,Output1):- 
     % NextP =\= P, should be useless given the test in clause above 
     listlen(Temp,Z), 
     Z > 1, !, % else ? 
     deleteUP(NextP,[_|Rest],Temp,Output), 
     appends(Temp,Output,Output1). 
1

您的問題說明會談。這是一個非常必要的程序性描述。試着首先關注關係應該描述的內容。其實,我還沒有理解2的最小長度是多少。

考慮使用預定義的append/3length/2來代替您自己的定義。但實際上,在你的例子中都不需要。

您可能想要使用專用結構q(X,Y,S,P)代替列表[X,Y,S,P]

目標appends([X,Y,S,P],Temp,Temp)顯示您認爲邏輯變量Temp可以像命令式語言中的變量一樣使用。但這種情況並非如此。默認情況下,SWI在這裏創建一個稱爲「無限樹」的非常奇怪的結構。暫時忘記這一點。

 
?- append([X,Y,S,P],Temp,Temp). 
Temp = [X, Y, S, P|Temp]. 

在SWI中有一種安全的方法來避免這種情況並自動檢測(某些)這樣的錯誤。打開發生檢查!

 
?- set_prolog_flag(occurs_check,error). 
true. 

?- append([X,Y,S,P],Temp,Temp). 
ERROR: lists:append/3: Cannot unify _G392 with [_G395,_G398,_G401,_G404|_G392]: would create an infinite tree 

目標=\=/2指算術不平等,你可能更喜歡dif/2代替。

避免! - 在這種情況下不需要。

length(L, N), N > 1通常更好地表示爲L = [_,_|_]

然而,主要問題是第三個和第四個參數應該是什麼。你真的需要先澄清一下。