2015-06-01 195 views
1

我正在處理Prolog中非常簡單的反向列表示例。Prolog返回true/false而不是變量

append(A, [], [A]). 
append(A, B, [A|B]). 

reverse([], ReversedList). 
reverse([A,B], ReversedList) :- 
    reverse(B, TemporaryList), 
    append(A, TemporaryList, ReversedList). 

append工作正常。但是,當我呼叫reverse時,解釋器不會響應像append這樣的變量,而只是寫入true或false。

這裏的日誌:

1 ?- consult('capitolo2'.pl). % file containing the code 
2 ?- append(a, [b,c,d], L). 
L = [a,b,c,d]. % ok, this works 
3 ?- reverse([a,b,c], L). 
false. % what? why that's not L = something? 

該平臺是SWI-Prolog的7.2在Windows

+1

這是一個相當不規範的定義['append'(http://www.swi-prolog.org/pldoc/man?predicate=append/3),通常是' append'被定義爲在列表上工作,例如'append([a,b,c],[x,y,z],L)==> L = [a,b,c,x,y,z]',http://stackoverflow.com/questions/11539203 /我怎麼做附加列表在序言 – npostavs

+0

看來,這不是問題。如果我將'append'重命名爲'my_append',它也是一樣的 – incud

+0

您也需要重新啓動Prolog系統。另外還有'[A,B]'這應該可能讀取'[A | B]'等等...... – false

回答

3

append/3

你有沒有單元測試呢?它工作正常嗎?您的append/3實施不正確。第一條

第一款:

append(A , [] , [A] ). 

簡單地創建從其第一個參數長度爲1的列表(不管它可能是)。鑑於此,如果你說:

append([1,2,3] , [] , X) . 

那你將獲得:

X = [ [1,2,3] ] 

長度爲1的列表,它包含了最初的原始第一個參數的唯一項目。第二條是同樣不正確的:

append(A , B , [A|B]). 

預先將第一個參數—不管它可能是,和其全部 —作爲鏈表的頭。鑑於此,如果你說的一樣:

append([1,2,3] , [a,b,c] , X) . 

那你將獲得:

X = [ [1,2,3] , a , b , c ] . 

長度爲4的列表中,第一項,其中是原來的第一個參數。

序言是描述語言:你描述的解決方案,讓發動機工作的東西了。 append/3斷言名單(第三參數append/3代表第一個參數和第二個參數的串聯

這裏是append/3實現,簡化了清晰:

append([]  , RL , RL) . % The concatenation of an empty left-hand list and a right hand list is the right hand list. 
append([LH|LT] , RL , CL) :- % The concatenation of a non-empty left-hand list and a right-hand list is true IF: 
    CL = [LH|CT] ,    % - The left-hand head and the concatenation head are the same, AND 
    append(LT , RL , CT)  % - recursively, the concatenated tail represents the conconcatenation of the left-hand tail and the right-hand list. 
    .       % Easy! 

當你彈出項關閉。左邊的列表中,它最終會分解成終止特殊情況,這可以簡化爲經典的實現:

append([]  , RL , RL  ) . 
append([LH|LT] , RL , [LH|CT]) :- append(LT , RL , CT) . 

reverse/3

同樣,您的reverse/3實施不正確。您的第一個條款:

​​

幾乎所有的東西都是空白列表的反面。由於您的ReversedList變量從未被引用,因此您的Prolog實現應至少在此處引發關於單例變量的警告。許多實現使它成爲一個錯誤。

你的第二子句:

reverse([A,B], ReversedList) :- 
    reverse(B, TemporaryList), 
    append(A, TemporaryList, ReversedList). 

說,一個具有兩個項列表的反向([A,B])由

  • 反轉在列表中的第二B)中獲得,和
  • 附加第一項(A)。

不完全正確的解決方案描述。你可以嘗試像

reverse([] , []) . % The empty list is already reversed, what with it being atomic and all. 
reverse([H|T] , R ) :- % a non-empty list can be reversed by decomposing it into its head and tail, and 
    reverse(T,T1) ,  % - reversing the tail, and 
    append(T1,H,R) .  % - appending the head to the now-reversed tail. 
+0

感謝您的答案。但是,這只是一個語法問題,我想寫reverse([A | B],ReversedList)的反向([A,B],ReversedList)。它仍然不起作用,但我知道算法不是'好的。 – incud

2

很可能還有其他的問題,但

  1. ​​

    幾乎肯定不是你想在這裏。空單的反面是一個空的列表,轉化爲

    reverse([], []). 
    
  2. 此外,

    reverse([A,B], ReversedList) 
    

    也可能不是你想要的。它是而不是列表頭A和尾B,而是一個2元素列表。

+0

結果是一樣的:( – incud

+0

還有至少另一個問題。請參閱更新。 –

+0

這是問題(nr2)。現在它不會返回我corrent結果,但這是我的算法中的問題 – incud

相關問題