我對Prolog完全陌生,我無法理解這段代碼。你會如何閱讀這4個子句?他們在做什麼?這段代碼是什麼意思?
a([]).
a([_|L]):-b(L).
b([_]).
b([_|L]):-a(L).
謝謝。
我對Prolog完全陌生,我無法理解這段代碼。你會如何閱讀這4個子句?他們在做什麼?這段代碼是什麼意思?
a([]).
a([_|L]):-b(L).
b([_]).
b([_|L]):-a(L).
謝謝。
由於@Repeat在他的評論暗示,運行一般查詢,這裏是你得到的:
| ?- a(Xs).
Xs = [] ? ;
Xs = [_,_] ? ;
Xs = [_,_] ? ;
Xs = [_,_,_,_] ? ;
Xs = [_,_,_,_] ? ;
Xs = [_,_,_,_,_,_] ? ;
Xs = [_,_,_,_,_,_] ? ;
...
A ND:
| ?- b(Xs).
Xs = [_] ? ;
Xs = [_] ? ;
Xs = [_,_,_] ? ;
Xs = [_,_,_] ? ;
Xs = [_,_,_,_,_] ? ;
Xs = [_,_,_,_,_] ? ;
Xs = [_,_,_,_,_,_,_] ? ;
Xs = [_,_,_,_,_,_,_] ? ;
...
所以a(Xs)
成功如果Xs
爲含有偶數個元素的列表,和b(Xs)
成功如果Xs
是含有奇數個的參數的列表。正如你所看到的,a/1
和b/1
在每種情況下成功兩次,除了a([]).
只成功一次。所以它不是確定列表長度奇偶性的有效謂詞。
讓我們重新編寫這些更多的描述性名稱:
even([]).
even([_|L]) :- odd(L).
odd([_]).
odd([_|L]) :- even(L).
現在讓我們來「讀」他們在說什麼:
[]
爲偶數列表[_|L]
爲偶數列表,如果L
是奇怪名單[_]
是一個奇怪的名單[_|L]
是一個奇怪的列表,如果L
是偶列表這些聽起來合乎邏輯,但爲什麼even/1
和odd/1
與even([])
異常成功兩次?如果您查看odd/1
的定義,則有兩種方法可以成功執行[_]
。一個是通過odd([_]).
條款。第二種是由第二odd/1
,因爲你會:
odd([_|[]]) :- even([]). % [_] == [_|[]]
由於兩個even/1
和odd/1
電話(與even([]).
除外)最終遞歸下降到呼叫odd([_])
,你會得到兩種解決方案。
把這些規則的Prolog,包括基本情況爲前:
even([]).
even([_,_|L]) :- even(L).
odd([_]).
odd([_,_|L]) :- odd(L).
現在的結果將是:
| ?- even(Xs).
Xs = [] ? ;
Xs = [_,_] ? ;
Xs = [_,_,_,_] ? ;
Xs = [_,_,_,_,_,_] ? ;
...
而且
| ?- odd(Xs).
Xs = [_] ? ;
Xs = [_,_,_] ? ;
Xs = [_,_,_,_,_] ? ;
...
繼CapelliC的建議使用DCG,可以寫成類似的規則:
even --> [] | [_,_], even.
odd --> [_] | [_,_], odd.
有了結果:
| ?- phrase(even, L).
L = [] ? ;
L = [_,_] ? ;
L = [_,_,_,_] ? ;
...
而且
| ?- phrase(odd, L).
L = [_] ? ;
L = [_,_,_] ? ;
L = [_,_,_,_,_] ? ;
...
odd([_]).
的情況,因爲它已經被
even([]).
的基本情況所涵蓋了。這也比上述s簡單一些因爲它利用了
even/1
和
odd/1
謂詞之間的相互依賴性(在上面的解決方案中,
even/1
和
odd/1
獨立存在)。
even([]).
even([_|L]) :- odd(L).
odd([_|L]) :- even(L).
或者,在DCG:
even --> [] | [_], odd.
odd --> [_], even.
的說法架構是非常重要的:
一)名單顯然是一個計數器,因爲我們從來不考慮的內容。
B)只是一個建議:讀邏輯生產,或DCG
a-->[];[_],b.
b-->[_];[_],a.
被稱爲 - 例如
?- phrase(a, [w,h,a,t]).
運行一些查詢的[標籤:序言,頂層]!查詢如'? - a(Xs).'或'? - b(Xs).' ... – repeat
當您擁有偶數個元素的列表時,它似乎會成功。 – Enigmativity
@Enigmativity它取決於你的意思。 'a'在偶數列上成功,'b'在奇數列上成功。它效率低下(在任何給定列表的幾乎所有情況下都會成功兩次)。 – lurker