2014-05-03 108 views
1

在此任務中遇到一些問題。獲取Prolog中列表的第二個元素

目前我已經試過這個,我知道這是錯誤的,因爲我不知道如何將L分成它的頭部和尾部,但是這是我要去做的想法。

second(L,E) :- [H | E | T] 

我認爲,E必須在頭後面,使它成爲第二個元素。不過,我對這種語言很陌生,並希望得到一些見解。我如何從寫出謂詞的方式得到這個頭和尾。對這個問題的一些見解將非常感謝。謝謝。

回答

7

可以移動統一到該條的頭部和簡單地寫爲:

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 = []. 
2

[詳細模式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]]如果你需要的頭/尾表示。你很少會需要使用點符號。

在句法友好(非點)形式中,非空列表可以由一個或多個離散元素表示,然後可選地由尾部表示(尾部在垂直條之後指定, |),其本身可以是列表或空列表[]。許多元素的列表,E1E2,...,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「)。

相關問題