簡體   English   中英

正確使用findall / 3,尤其是最后一個結果參數

[英]Correct use of findall/3, especially the last result argument

我是Prolog的初學者,我正在處理一個可能對您來說很愚蠢的問題,但是我真的不明白我在做什么錯! 好的,我有這個文件fruits.pl,里面有這樣的東西:

fruit(apple,small,sweet).
fruit(lemon,small,nosweet).
fruit(melon,big,sweet).

我已經(在該文件中創建了一個coexist(X,Y)原子,該原子檢查是否可以將兩個水果放到盤子中。它正常工作!但是現在我無法創建以參數為參數的suggest(X)水果,並返回可以放在同一盤子中的水果清單。問題是我正在嘗試制作類似的東西

suggest(X) :- findall(Y,fruit(Y,_,_), List), coexist(X,Y).

你怎么看? 每次我嘗試在swi序言中運行此命令時,都會出現一個警告“單變量”,當我按

suggest(apple).

然后它說假..對不起我的英語:/

Prolog中的謂詞不返回任何內容。 您的目標是否得到滿足,您可以將其解釋為返回truefalse

您的謂詞suggest(X)應該包含另一個參數,該參數將綁定到與X一起使用的水果列表中。 一個選項是: suggest(X, List) ,它描述以下關系: List表示與X在一起的所有水果。 然后,您可以問:

?- suggest(apple, List).
List = [pear, cherry].

目標findall(Y, ... , ...)在內部使用Y變量,並且在滿足目標后, Y仍未綁定。 因此,您應該在findall/3的第二個參數內移動coexist(X,Y) ,這是所有可能滿足的目標。 下面釷規則,如果只能X被實例化( suggest(+X, -List) )。

suggest(X, List) :- findall(Y, (fruit(Y,_,_), coexist(X, Y)), List).

您可以閱讀以下內容:“ List代表與X共存的所有水果Y ”。

當您嘗試在Prolog中定義謂詞時,首先假設您已經編寫了該謂詞,然后開始想象如何使用它。 也就是說,您要提出什么查詢。

在我看來, coexist/2已經描述了您想要的內容。 順便說一句, may_coexist/2可能是一個更具描述性的名稱。 為什么要在單獨的列表中? 為什么要使用fruit/3 但是為了這個問題,讓我們假設這是有道理的。 因此,基本上,您現在將擁有一個fruit_compatible/2關系:

fruit_compatible(F, G) :-
   fruit(F, _, _),
   may_coexist(F, G),
   fruit(G, _, _).  % maybe you want to add this?

現在,假設您也需要此列表。 因此,您將擁有一個fruit_suggestions/2關系。 如何使用它?

?- fruit_suggestions(apple, L).
L = [cherry, pear].

還是...應該是L = [pear, cherry] 或兩者?

?- fruit_suggestions(lemon, L).
L = [orange].

因此,每當我想要一個建議時,我都必須想到一個水果。 一直在想:那應該是什么水果? 幸運的是,Prolog中的要求較低:只需使用變量而不是結果! 現在,我們應該立即獲得所有建議!

?- fruit_suggestions(F, L).
F = apple, L = [cherry, pear] ;
F = lemon, L = [orange] ;
F = cromulon, L = [embiggy, mushfruit].

因此,我們需要實現它,使其表現出這種方式。 單獨使用findall/3並不能解決這個問題。 手動實施它並非易事。 但是有setof/3正是以這種方式處理變量。 許多細微的細節設計決定已經做出,就像清單將按升序排列一樣。

fruit_suggestions(F, L) :-
   setof(G, fruit_compatible(F, G), L).

編輯:由於下面的討論,這將是一個允許空列表的解決方案。 請注意,這聽起來微不足道,但事實並非如此。 要查看此信息,請考慮以下查詢:

?- fruit_suggestions(F, []).

這是什么意思? F應該是什么? 那些根本沒有結果的東西嗎? 在這種情況下,我們將不得不為所有問題提供解決方案。 F = badger ; F = 42 ; ... F = badger ; F = 42 ; ... F = badger ; F = 42 ; ... 這很可能沒有多大意義。 可能想要的是與所有事物都不兼容的那些水果。 為此,我們需要添加一個新規則:

fruit_suggestions(F, []) :-
   setof(t,X^Y^fruit(F,X,Y),_),
   \+ fruit_compatible(F, _).
fruit_suggestions(F, L) :-
   setof(G, fruit_compatible(F, G), L).

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM