在此任務中遇到一些問題。獲取Prolog中列表的第二個元素
目前我已經試過這個,我知道這是錯誤的,因爲我不知道如何將L分成它的頭部和尾部,但是這是我要去做的想法。
second(L,E) :- [H | E | T]
我認爲,E必須在頭後面,使它成爲第二個元素。不過,我對這種語言很陌生,並希望得到一些見解。我如何從寫出謂詞的方式得到這個頭和尾。對這個問題的一些見解將非常感謝。謝謝。
在此任務中遇到一些問題。獲取Prolog中列表的第二個元素
目前我已經試過這個,我知道這是錯誤的,因爲我不知道如何將L分成它的頭部和尾部,但是這是我要去做的想法。
second(L,E) :- [H | E | T]
我認爲,E必須在頭後面,使它成爲第二個元素。不過,我對這種語言很陌生,並希望得到一些見解。我如何從寫出謂詞的方式得到這個頭和尾。對這個問題的一些見解將非常感謝。謝謝。
可以移動統一到該條的頭部和簡單地寫爲:
second([_, Second| _], Second).
爲列表中的符號是寫由逗號分隔的初始元素,然後豎線分開列表尾部,即包含其餘元素的列表。一些例子,你可以嘗試在序言頂級的解釋應該更清楚:
?- [1, 2, 3] = [Head| Tail].
Head = 1,
Tail = [2, 3].
?- [1, 2, 3] = [First, Second| Tail].
First = 1,
Second = 2,
Tail = [3].
?- [1, 2, 3] = [First, Second, Third| Tail].
First = 1,
Second = 2,
Third = 3,
Tail = [].
[詳細模式ON]
一個列表在序言要麼是空列表[]
或一個頭部和一個尾部,其在技術上由「點」函數表示,在Prolog中爲'.'(H,T)
,但是Prolog提供語法上更友好的表示,[H|T]
。 頭,H
是一個元素,並且尾部,T
本身就是一個列表。如果你看看LISP,它們分別是列表的汽車和cdr。在Prolog中,豎線|
將頭部與尾部分開。
在Prolog的提示,你可以輸入X = '.'(H,T).
,看看你會得到什麼:
| ?- X ='.'(H,T).
X = [H|T]
yes
| ?-
如果你有一個元素的列表,這將是[X]
,但在技術上是[X|[]]
或'.'(X,[])
。如果你有兩個元素的列表,它可以寫成:
[X,Y]
[X|[Y]]
'.'(X,[Y])
[X|'.'(Y,[])]
'.'(X,'.'(Y,[]))
這些形式的所有工作,但最常見的形式是[X,Y]
,或者根據上下文,[X|[Y]]
如果你需要的頭/尾表示。你很少會需要使用點符號。
在句法友好(非點)形式中,非空列表可以由一個或多個離散元素表示,然後可選地由尾部表示(尾部在垂直條之後指定, |
),其本身可以是列表或空列表[]
。許多元素的列表,E1
,E2
,...,En
可以寫在許多方面,概括了上述想法:
[E1,E2,...,En]
[E1|T] % T = [E2,E3,...,En]
[E1,E2|T] % T = [E3,E4,...,En]
[E1,...,Ek|T] % T = [Ek+1,Ek+2,...,En]
[E1|[E2|T]] % T = [E3,E4,...,En]
[E1|[E2|...[Ek|T]]...]] % T = [Ek+1,Ek+2,...,En]
所以兩個豎線(|
)沒有意義的形式[X|Y|T]
但他們的表單,[X|[Y|T]]
。由於尾部T
本身是一個列表(或[]
),它遵循與原始列表相同的表示規則。因此,該列表本質上是一種適用於遞歸的結構。 Prolog中的許多操作列表的操作都是遞歸的,通過操作頭部,然後調用自己的尾部,並在看到空列表[]
時結束。
如果我統一兩個清單,L1 = L2
,我希望它成功,那麼(1)名單將需要相同的長度,和(2)L1
每個元素都必須unifiable與它在L2
相應元素。因此,如果我在Prolog提示符下執行此操作:
| ?- [X,2,Z] = [1,Y,3].
X = 1
Y = 2
Z = 3
yes
| ?-
我已成功統一顯示變量的值。我也可以這樣做:
| ?- [X|T] = [1,2,3,4].
T = [2,3,4]
X = 1
yes
| ?-
的Prolog能夠統一,如果X
進行實例化1
和尾部的兩個列表,T
進行實例化[2,3]
。我也可以這樣做:
| ?- [X,Y|T] = [1,2,3,4].
T = [3,4]
X = 1
Y = 2
yes
| ?-
正如Paolo指出的那樣,這顯示瞭如何獲得第二個元素。你也可以這樣來做:
| ?- [X|[Y|T]] = [1,2,3,4].
T = [3,4]
X = 1
Y = 2
yes
| ?-
這真的意味着同樣的事情,只是看着有不同的語法:第二個元素是列表的尾部或頭部(在LISP「的汽車的cdr「)。