2015-06-16 23 views
3

列出的名單上有列出的這份名單:壓平的Prolog

L = [[[a,b],[d,e]],[[m,f],[p,o]],[[r,l],[v,d]]]. 

我想寫使用序言,以展它,它變成這樣一種方式的函數:

L = [[a,b],[c,d],[m,f],[p,o],[r,l],[v,d]]. 

有什麼建議嗎? 謝謝。

+0

查看此答案http://stackoverflow.com/questions/27263004/flattening-only-one-level-of-a-list-in-prolog – vmg

+2

你想寫一個*謂詞*(一個Prolog規則),而不是*函數*。 Prolog沒有功能。 :)這個問題留下了一些問題。例如,原始列表是否可以有多於3個級別的列表?如果是這樣,你想刪除哪個級別?如果原始列表只有1或2個級別,該怎麼辦?它應該失敗嗎?或者產生原始列表?或者是其他東西? – lurker

+0

上下文是我使用謂詞findall,結果它給了我這個列表,我將在另一個謂詞中使用,問題是findall給了我這個列表,它總是3個級別。 –

回答

0

使用predicate append/2

 
?- L = [[[a,b],[d,e]],[[m,f],[p,o]],[[r,l],[v,d]]], append(L, R). 
L = [[[a, b], [d, e]], [[m, f], [p, o]], [[r, l], [v, d]]], 
R = [[a, b], [d, e], [m, f], [p, o], [r, l], [v, d]]. 

你應該看看at the implementation by SWI-Prolog並複製它,如果你需要。如果您必須在GNU-Prolog中執行此操作,請不要使用must_be/2

但是如果你需要這一點,因爲findall/3,請記住,有也可能是一個findall/4可用(不適用於GNU-Prolog的,但SWI-Prolog有它):

 
$ swipl 
Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.2-25-gf8c39d8) 
Copyright (c) 1990-2015 University of Amsterdam, VU Amsterdam 
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software, 
and you are welcome to redistribute it under certain conditions. 
Please visit http://www.swi-prolog.org for details. 

For help, use ?- help(Topic). or ?- apropos(Word). 

?- findall(X, between(1,3,X), Xs, Rest), findall(Y, between(7,11,Y), Rest). 
Xs = [1, 2, 3, 7, 8, 9, 10, 11], 
Rest = [7, 8, 9, 10, 11]. 

幾乎所有的情況下你需要拼湊一個列表可以避免使用差異列表。

+0

我實際上使用的是GNU prolog,它並沒有讓事情變得簡單,但我使用了append/3,我寫了這個謂詞:new_append([T1,T2,T3],Result): - append(T1,T2,Res),追加(RES,T3,結果)。但它給了我類似於:[a,b],[c,d],[e,f],[g,h],[i,j],[k,l] ...只是元素而不是列表列表(我同意我的謂詞相當主觀,因爲我只使用3個列表): –

+0

因爲我使用Gnu prolog,append/2不起作用,它給了我這個錯誤:未捕獲的異常:錯誤(exists_error(procedure,append/2),top_level/0) –

+0

它終於工作了,我做了什麼是我在我的謂詞每次在我的謂詞之後每次都找到後面的append,這是爲了防止它可以幫助某人 –

0
possible_moves(Tray,PossibleMoves):- 
    findall([J,1,X,Y],possible_move(Tray,[J,1,X,Y]),T1), 
    findall([J,2,X,Y],possible_move(Tray,[J,2,X,Y]),T2), 
    append(T1,T2,Res), 
    findall([J,3,X,Y],possible_move(Tray,[J,3,X,Y]),T3), 
    append(Res,T3,PossibleMoves).