2013-04-22 56 views
-1

編寫需要的元素本身名單和 打印在每行的內部列表中的元素列表的規則列表的列表:有關程序的聲明意義有些疑惑,打印在序言

例:

? - printList [[1,a],[2,b]])。

2 B

溶液了下列之一:到達基礎案例

/* BASE CASE: The list is empty, so there is nothing to print */ 
printList([]). 

printList([P|R]):- printList(P), 
        !, 
        nl, 
        printList(R). 

printList([X|R]):- write(X), 
        !, 
        printList(R). 

我有的printList規則當列表是空的,在這種情況下,沒有什麼可打印的。

如果我的基本情況我不是(在列表不爲空),它調用第二條規則的printList([P | R]),現在我有我的第一個疑問:

元素P是一個列表,因爲Prolog自動處理一個內部列表作爲一個元素?

所以,如果我有類似:

[[1,],[2,B],[3,C],[4,D]]我有Prolog的自動匹配在這種方式:

P = [1,](第一列表作爲頭元件)

R = [[2,b],[3,C],[4,d] ](其他3個列表是尾部列表的元素)

然後程序在頭元素(第一個列表)上調用謂詞謂詞,並且此版本的規則寫入當前列表中的所有元素。

這是正確的解釋嗎?

現在我對這個項目的跟蹤一些疑問,例如,如果我執行該語句我獲得以下跟蹤:

[trace] ?- printList([[1,a], [2,b]]). 
    Call: (6) printList([[1, a], [2, b]]) ? creep 
    Call: (7) printList([1, a]) ? creep 
    Call: (8) printList(1) ? creep 
    Fail: (8) printList(1) ? creep 
    Redo: (7) printList([1, a]) ? creep 
    Call: (8) write(1) ? creep 
1 
    Exit: (8) write(1) ? creep 
    Call: (8) printList([a]) ? creep 
    Call: (9) printList(a) ? creep 
    Fail: (9) printList(a) ? creep 
    Redo: (8) printList([a]) ? creep 
    Call: (9) write(a) ? creep 
a 
    Exit: (9) write(a) ? creep 
    Call: (9) printList([]) ? creep 
    Exit: (9) printList([]) ? creep 
    Exit: (8) printList([a]) ? creep 
    Exit: (7) printList([1, a]) ? creep 
    Call: (7) nl ? creep 

    Exit: (7) nl ? creep 
    Call: (7) printList([[2, b]]) ? creep 
    Call: (8) printList([2, b]) ? creep 
    Call: (9) printList(2) ? creep 
    Fail: (9) printList(2) ? creep 
    Redo: (8) printList([2, b]) ? creep 
    Call: (9) write(2) ? creep 
2 
    Exit: (9) write(2) ? creep 
    Call: (9) printList([b]) ? creep 
    Call: (10) printList(b) ? creep 
    Fail: (10) printList(b) ? creep 
    Redo: (9) printList([b]) ? creep 
    Call: (10) write(b) ? creep 
b 
    Exit: (10) write(b) ? creep 
    Call: (10) printList([]) ? creep 
    Exit: (10) printList([]) ? creep 
    Exit: (9) printList([b]) ? creep 
    Exit: (8) printList([2, b]) ? creep 
    Call: (8) nl ? creep 

    Exit: (8) nl ? creep 
    Call: (8) printList([]) ? creep 
    Exit: (8) printList([]) ? creep 
    Exit: (7) printList([[2, b]]) ? creep 
    Exit: (6) printList([[1, a], [2, b]]) ? creep 
true. 

這對我來說是很清楚(我覺得我以前的推理是正確的),但我不理解爲何當它到達它調用就可以了的printList關係(這是一個簡單的元素,而不是一個列表)內部列表中的元素,例如這裏:

Call: (8) printList(1) ? creep 
    Fail: (8) printList(1) ? creep 

日C計劃審議了原始列表的第一個列表,然後將它必須打印的第一個元素,爲什麼叫這個簡單的元素

的printList關係是不是因爲這個簡單的元素可能反過來是內部列表嗎?

是這樣的:

[[[1.1,A1,A2],[1.2,B1,B2]],[2,b]的](其中我有一個包含2所列出的列表和第一個元素是包含2所列出所以程序檢查列表如果一個元素是一個元素或內部列表

回答

2

我覺得你過於思前想看看代碼:?

printList([P|R]):- printList(P), 

就在那裏你可以看到printList/1正與名單的頭。事實上,printList/1的所有規則都與列表和列表相匹配,這是人類可以立即看到的事實。但序言沒有「通知」這一事實,所以如果你是打電話,說,

printList([1]) 

第一個匹配的規則是上面的一個,所以它會立即試圖統一printList(1)。這當然會失敗,因爲1不是一個列表,因此不符合printList/1的任何規則。序言然後回溯並嘗試下一個規則,這是啓動這樣的一個:

printList([X|R]):- write(X), 

這顯然將統一[1],其中X = 1,R = [],因此它明顯地將寫第一個元素,一個,然後照常進行。這裏並沒有涉及「內部列表」的魔術,據我所知,它根本不是Prolog中的一個概念(如果在編譯器中處理這樣的事情,它對Prolog的用戶來說是隱藏的)。

序言不是通靈;它必須嘗試規則來判斷它們是否失敗,即使這種嘗試實質上是Horn子句頭部的模式匹配失敗。

我無法區分你的第一個問題和你的第二個問題,所以我希望這兩個答案都可以。 :)

+0

Tnx這麼多;-) – AndreaNobili 2013-04-22 14:11:09