2010-09-26 87 views
4

我需要編寫一組子列表,其中列出整數列表並返回單個列表,並將所有元素加倍。Prolog:將列表中的每個元素的值加倍並返回單個列表

例如:

?- double([[1,2],[3]], X). 
Yes 
X = [2,4,6] 

我有一組名爲條款是mega_append從列表的列表返回一個列表。

例如:

?- mega_append([[1,2],[3]], X). 
Yes 
X = [1,2,3] 

這裏是我的進步(M_A是短期的mega_append):

double([],[]). 
double(List,[H1|T1]) :- 
    m_a(List,[H2|T2]), 
    H1 is 2 * H2, 
    double(T2, T1). 

我會盡力解釋我怎麼想它會工作。我將第一個列表弄平並將其分解爲頭部和尾部(H2和T2)。我將第二個列表分爲頭部和尾部(H1和T1)。我檢查以確保H1(雙倍值)等於H2(原始值)的2倍。如果是的話,我檢查清單的其餘部分。最終如果他們都匹配正確,我應該留下兩個空列表,應該匹配第一個條款並返回yes。

只有一個值時才起作用(例如:double([[1]], X))。任何人都可以提供任何見解我做錯了什麼?我的邏輯或代碼不正確?

+0

如果mega_append獲取單個列表而不是列表列表,會發生什麼情況?防爆。 ? - mega_append([2,3],X)。 – Zeriab 2010-09-26 23:32:57

+0

它返回false。 – birderic 2010-09-26 23:43:50

回答

2

你的問題是,T2是一個單一的列表,所以遞歸調用後列表不是列表的列表。

要解決此問題,您可以先使用mega_append將列表弄平,然後使用輔助謂詞處理拼合列表。 也就是說雙看起來就像這樣:

double([],[]). 
double(List,X) :- 
    m_a(List,FList), 
    double_aux(List, FList). 

編輯: 這是一種方式,因爲你想看到一個只使用一個子句。 我建議使用輔助謂詞。

double([],[]). 
double([[]],[]). 
double(List,[H1|T1]) :- 
    mega_append(List,[H2|T2]), 
    H1 is 2 * H2, 
    double([T2], T1). 
+0

謝謝。我能夠用這種方法搞清楚。儘管如此,我仍然相信存在一種只使用一組子句的方法。 – birderic 2010-09-27 14:11:40

+0

通常會有一個'flatten/2'過程來完成你的'm_a/2'的功能。 – rvirding 2010-09-27 18:43:12

+0

確實有。我用一個例子編輯了我的帖子,但是使用輔助謂詞的imo比這個例子更好。 (可能有一些我看不到atm的好方法。) – Zeriab 2010-09-27 20:09:22

2

使用,我們定義nonterminaldouble//1這樣的:

:- use_module(library(clpfd)). 

double([])  --> []. 
double([D|Ds]) --> {DD #= D*2}, [DD], double(Ds). 

讓我們使用查詢,phrase/2運行一些, apply:foldl/4,和非終結double//1

 
:- use_module(library(apply)). 

?- phrase(foldl(double,[[1,2],[3]]),Xs). 
Xs = [2,4,6]. 

?- phrase(foldl(double,[[A,B],[C]]),[2,4,6]). 
A = 1, B = 2, C = 3. 

想要了解更多使用的示例? 閱讀this SICStus Prolog manual page!

相關問題