2013-02-11 180 views
3

我正在開發用Prolog編寫的應用程序。我得到了一個要過濾元素列表並刪除那些不符合特定約束或條件的元素,並保持原始列表順序的問題。我認爲最好的方式做這將是這樣的:在Prolog中篩選列表

filter([],Filtered). 
filter([L|List],[F|Filtered]) :- 
    /* Conditions are met: bypass the element to the filtered list */ 
    check_conditions(L), 
    filter(List,Filtered). 
filter([L|List],Filtered) :- 
    /* Conditions are not met: do not include the element in the filtered list */ 
    filter_aborts(List,Filtered). 

接受它作爲一個解決我的問題,我想試試看(獨立)之前,所以我編譯和運行我的代碼(SWI -Prolog)並測試了幾種情況。當我使用硬編碼列表中的Prolog鍵入查詢(或任何你想將它命名),我得到了這樣的事情:

?- filter([id01,id02,id03,id04,id05,id06],F). 
F = [id03, id05, id06|_G1024] . 

肯定是過濾列表,但我得到這個實例名稱「_G1024」在它的結尾。我知道這是因爲F沒有實例化,但我不知道解決方案是什麼。此外,如果我嘗試做一些像進入清單作爲一個實例化的變量不同,我所得到的是更奇怪:

?- L=[id02,id03,id04,id05,id06]. 
L = [id02, id03, id04, id05, id06]. 

?- filter(L,F). 
L = [] ; 
L = [id01], 
F = [id01|_G347] ; 
L = [id01, id01], 
F = [id01, id01|_G403] 
... and so on. 

應該是分配一次變量不是Prolog的變量?我的程序實際上是否改變了L或者我沒有正確理解它?除此之外,由於我是Prolog新手,因此對於我的序言-let的說法 - 「風格」,我將不勝感激。

回答

4

你的基地遞歸應該寫

filter([],[]). 

,你有一個錯字

filter([L|List],[L|Filtered]) :- 
... 

代替(第二)長,你有單˚F

+0

我剛剛發表評論當我閱讀您的答案時發現(愚蠢)錯誤。非常感謝,那是錯誤!即使如此,解釋第二個錯誤是什麼? – 2013-02-11 14:30:01

+0

我在寫下這個問題時考慮了一個錯字,因爲寫的程序會輸出一個* not instanced *變量的列表 – CapelliC 2013-02-11 15:05:07

7

您使用SWI-Prolog的,所以你可以根據你的條件編寫一個成功或失敗的謂詞,然後使用包括(Predidate,Lst,Success)。對於axample

include(check_conditions,Lst, Success) 
+0

您是對的(+1),所提供的謂詞會更好地用include/3編寫,但我最終自己寫了一個過濾器/ 3,因爲我想(爲了一點效率)能夠改變接受的元素 – CapelliC 2013-02-11 14:18:52

+0

Tanks @ joel76!我不知道這個「include/3」謂詞。我會在這裏使用它,因爲它完全符合我的需求。 – 2013-02-11 14:32:00