2016-04-28 62 views
1

我有兩個列表L1L2的findall/3的子列表符合一定標準的

L1=[1,4,5,6,7,8]. 
L2=[2,3]. 

和一個謂語:

related(X,Y). 

我想找到一個列表L3

  1. 這是L1的子列表

  2. 在其中L3所有元件是用於Y,其中任何的L2是解決方案值的X

換言之,進料的L2所有值成X,並找出解決辦法取出L1的哪個值將爲Y的相應解決方案。

+2

您的標題說明要使用什麼('findall/3')只是在第二個參數中描述您的條件。你想找到所有'X',例如'member(X,L1)'(你的第一個條件),那麼你有一個連接條件,(b)包含。你可以在'findall/3'中有一個複合表達式:'findall(X,(member(X,L1),...,...),L3)。 – lurker

回答

2

使用findall/3這是可以做到這樣(如果我正確地理解你的條件):

findall(Y, (member(Y, L1), member(X, L2), related(X, Y)), L3). 

在我的評論,我有X張望了一下混合由於誤讀你的條件,但這個想法是還是一樣。您只需要建立適當的目標作爲findall/3的第二個參數即可獲得所需的結果。


如果你想要獨一無二的,有序的結果,你可以使用 setof/3

setof(Y, (member(Y, L1), member(X, L2), related(X, Y)), L3). 
+0

唯一我能想到的問題是應該因爲應該只存在一個,所以對'member(X,L2),related(X,Y)'使用'once'。很好回答btw。 +1。 –

+0

@WillemVanOnsem謝謝!,是的,很好。在這種情況下,我可能會使用'setof/3'。使用'once/1'時,需要注意不要刪除有效的,獨特的解決方案。目前還不清楚'related/2'的行爲是什麼。 – lurker

+0

一套仍然不完全等同,我認爲。結果應該是一個子列表。原始列表可以包含重複項,這些重複項應該可能在結果中重複。儘管如此,這個問題有點低估了。 –

1

findall/3的結構爲:

findall(+Template, :Goal, -Bag) 

其中:

  • Bag是結果列表中你想獲得;
  • Goal是應該成功的謂詞(或謂詞的組合);和
  • Template是描述結果格式的表達式。

現在讓我們用這個謂詞做一些施工:

  1. 這是您正在尋找所有元素YL1L1

一個子表,所以模板顯然是X1,目標是l東部包含member(X,L1)。所以,現在或findall/3被成形爲:

findall(Y,(member(Y,L1),...),L3) 
  • 其中的L3所有元件是用於Y,溶液,其中任何的L2是解決方案值的X
  • 由於應該有至少一個XL2使得related(X,Y)成立。這意味着我們使用once/1來強制執行從發現一個X的那一刻起,我們的呼叫終止(並且不發生Y的重複),使得XL2related/2成立的元素(member/2)。 ...因而等於:

    once((member(X,L2),rel(X,Y))) 
    

    還是現在的完整版:

    findall(Y,(member(Y,L1),once((member(X,L2),rel(X,Y)))),L3) 
    

    例子:

    鑑於例如:

    rel(2,1). 
    rel(3,1). 
    rel(2,4). 
    rel(3,7). 
    

    結果是:

    ?- L1=[1,4,5,6,7,8],L2=[2,3],findall(Y,(member(Y,L1),once((member(X,L2),rel(X,Y)))),L3). 
    L1 = [1, 4, 5, 6, 7, 8], 
    L2 = [2, 3], 
    L3 = [1, 4, 7]. 
    

    因此1只會出現一次,而Y=1有兩個X,條件成立。