我有兩個列表L1
和L2
:的findall/3的子列表符合一定標準的
L1=[1,4,5,6,7,8].
L2=[2,3].
和一個謂語:
related(X,Y).
我想找到一個列表L3
:
這是
L1
的子列表在其中
L3
所有元件是用於Y
,其中任何的L2
是解決方案值的X
換言之,進料的L2
所有值成X
,並找出解決辦法取出L1
的哪個值將爲Y
的相應解決方案。
我有兩個列表L1
和L2
:的findall/3的子列表符合一定標準的
L1=[1,4,5,6,7,8].
L2=[2,3].
和一個謂語:
related(X,Y).
我想找到一個列表L3
:
這是L1
的子列表
在其中L3
所有元件是用於Y
,其中任何的L2
是解決方案值的X
換言之,進料的L2
所有值成X
,並找出解決辦法取出L1
的哪個值將爲Y
的相應解決方案。
使用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).
唯一我能想到的問題是應該因爲應該只存在一個,所以對'member(X,L2),related(X,Y)'使用'once'。很好回答btw。 +1。 –
@WillemVanOnsem謝謝!,是的,很好。在這種情況下,我可能會使用'setof/3'。使用'once/1'時,需要注意不要刪除有效的,獨特的解決方案。目前還不清楚'related/2'的行爲是什麼。 – lurker
一套仍然不完全等同,我認爲。結果應該是一個子列表。原始列表可以包含重複項,這些重複項應該可能在結果中重複。儘管如此,這個問題有點低估了。 –
findall/3
的結構爲:
findall(+Template, :Goal, -Bag)
其中:
Bag
是結果列表中你想獲得;Goal
是應該成功的謂詞(或謂詞的組合);和Template
是描述結果格式的表達式。現在讓我們用這個謂詞做一些施工:
- 這是您正在尋找所有元素
Y
在L1
的L1
一個子表,所以模板顯然是X1
,目標是l東部包含member(X,L1)
。所以,現在或findall/3
被成形爲:
findall(Y,(member(Y,L1),...),L3)
- 其中的
L3
所有元件是用於Y
,溶液,其中任何的L2
是解決方案值的X
由於應該有至少一個X
在L2
使得related(X,Y)
成立。這意味着我們使用once/1
來強制執行從發現一個X
的那一刻起,我們的呼叫終止(並且不發生Y
的重複),使得X
是L2
和related/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
,條件成立。
您的標題說明要使用什麼('findall/3')只是在第二個參數中描述您的條件。你想找到所有'X',例如'member(X,L1)'(你的第一個條件),那麼你有一個連接條件,(b)包含。你可以在'findall/3'中有一個複合表達式:'findall(X,(member(X,L1),...,...),L3)。 – lurker