1

I'm a beginner in Prolog and I am dealing with a problem that might seem stupid to you, but I really can't understand what I'm doing wrong! Ok, I have this file fruits.pl and inside that I have something like this:

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

I have already (inside that file made a coexist(X,Y) atom that checks if two fruits can be put together in a plate. It works fine! But now I can't create a suggest(X) that takes as a parameter a fruit and returns a list of fruits that can be put together in the same plate. The thing is I was trying to make something like that

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

What do you think? Every time I try to run this in swi prolog there is a warning 'singleton variable' and when I press

suggest(apple).

then it says false.. sorry for my english :/

4

2 回答 2

2

Prolog 中的谓词不返回任何内容。您有满足与否的目标,您可以将其解释为返回truefalse

您的谓词suggest(X)应包含另一个参数,该参数将绑定到与X. 一个选项是:suggest(X, List)它描述了以下关系:List表示与 一起出现的所有水果X。然后,你可以问:

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

目标在内部findall(Y, ... , ...)使用该Y变量,并且Y在满足目标后仍然未绑定。因此,您应该进入coexist(X,Y)第二个参数,findall/3即以所有可能的方式满足的目标。以下规则仅在X实例化 ( suggest(+X, -List)) 时才有效。

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

你可以这样解读:“代表所有与”共存的List果实。YX

于 2014-06-18T15:30:05.917 回答
2

当您尝试在 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 ; ...。很可能这没有多大意义。可能是那些与一切不相容的果实。为此,我们需要添加一条新规则:

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).
于 2014-06-18T18:12:33.903 回答