2010-11-11 78 views
1

我幾個星期前一直在研究Prolog,而我一直在困擾的一些小問題是使用append提出的解決方案。Prolog中的簡單附加問題

舉例來說,如果我有一個模式匹配規則,看起來像

pattern(foo(X,Y), L1, L) :- 
    % some code to go through a list (where the foo-pattern is) 
    % and add the pattern to the list L if it matches` 

我知道,追加/ 3是去這裏的路,但..升未知開始即不接地,因爲我們開始遞歸它開始填充匹配模式的列表。然而,我總是對最初發生的事情感到困惑,即當L不被磨光時。

例如,這裏就是我們想要得到的所有匹配的模式列表時,第一個參數是可能的模式列表的碼斷位:

pat([foo(X,Y)|L1], R, L) :- 
    append(foo(X,Y),R,L), 
    pat(L1, R, [D|L]). 
pat([_|L1], R, L2) :- 
    pat(L1, R, L2). 

非常感謝。

回答

0

你可能會逃避一個不使用append/3的解決方案。例如,請考慮以下謂詞,filter/3

filter(_Pattern, [], []). 
filter(Pattern, [E|Es], Matches) :- 
    Pattern \= E, !, 
    filter(Pattern, Es, Matches). 
filter(Pattern, [E|Es], [E|Matches]) :- 
    filter(Pattern, Es, Matches). 

filter/3的第一條是基本情況,其中,如果有什麼(左)在第二個參數列表相匹配,那麼我們就得到一個空列表。由於我們沒有考慮Pattern,所以它被忽略(因此前面的_針對變量)。

filter/3試驗的第二條款,以查看是否Pattern,這可能被綁定到一個術語(例如,foo(X,Y)),可以統一與列表的E第一元件相匹配。 \=運算符將會成功時,它的參數不能統一,所以如果這個成功,當我們不匹配E的模式,並可以扔掉它並繼續(注意測試後切入!提交到這個分支)。

filter/3最後(第三)子句是在第二子句依賴的,因爲它只是簡單地傳遞E到假定它的匹配Pattern的最後一個參數列表Matches,因爲前述條款未能確定它是不是一場比賽。請注意,我們將E附加到列表中,方法是將列表結構綁定到輸出,使Matches子列表解除綁定;完整的Matches列表只有在達到基本情況後纔會完全綁定,一旦我們用完第二個參數中的匹配條件,將其綁定到空列表[],創建類似[E1,E2,...,En|[]]的匹配模式;每個E1En匹配模式;這個詞相當於名單[E1,E2,...,En]

測試這個謂詞如下給出:

?- filter(foo(X,Y), [a,b,foo(x,y),c(f),foo(v(3),Z),5], L). 
L = [foo(x, y), foo(v(3), Z)] ; 
false. 

注意,一切unifiable與圖案foo(X,Y)這裏被過濾到必要L

最後一點:在你的代碼中,append(foo(X,Y),R,L)總是會失敗,因爲append/3只對列表進行操作;您可能想撥打append([foo(X,Y)],R,L),但在這種情況下,您只需簡單地使用L = [foo(X,Y)|R]作爲簡寫。

編輯:要匹配,你有可能的模式列表匹配和篩選您的特定情況下,這裏是另一個謂語,filter_list/3

filter_list(_Patterns, [], []). 
filter_list(Patterns, [E|Es], Matches) :- 
    filter(E, Patterns, []), !, 
    filter_list(Patterns, Es, Matches). 
filter_list(Patterns, [E|Es], [E|Matches]) :- 
    filter_list(Patterns, Es, Matches). 

注意filter_list/3依賴於我以前的定義並且使用完全相同的策略實施:如果EPatterns中的任何一個都不匹配(即,這是filter(E, Patterns, [])成功的情況),那麼我們忘記E並繼續,否則(最後一句)我們保留它。測試給了我們:

?- filter_list([foo(X,Y),bar(X),b], [a,b,foo(X,Y),c], L). 
L = [b, foo(X, Y)] ; 
false. 
0

我沒有看父親比...追加(富(...標準附加/ 3謂詞名單工作的示例代碼追加(FOO(。任何東西),...都不會匹配它的任何一個子句,因此你的第一個子句應該總是失敗,第二個子句應該失敗或者不能構造一個無限制的變量列表,當內存耗盡時最終會崩潰。你最終想在這裏做什麼,這對我來說並不是很清楚,但是這聽起來像你不想在模式匹配中尋找與列表中的項目相匹配的項目,爲什麼你認爲追加/ 3路要走嗎?