首页 > 解决方案 > Prolog:如何检查列表是否包含来自众多事实的列表

问题描述

我是 prolog 的新手,并试图弄清楚如何解决这个问题。
Number1、number2 和 number3 是蛋糕名称。
Chocolate,mango,lemon... 是成分和数字,之后是我不需要用于此查询的价格,但它们必须存在。

icecream(number1,  [chocolate,mango,lemon], 1.99).

icecream(number2, [vanille,lemon ], 1.79).

icecream(number3, [almonds, kiwi, walnut], 2.50).

询问:

which_icecream( [vanille,lemon,chocolate,mango],  S).

      S = number1;

      S = number2.

谢谢!

标签: listprolog

解决方案


member/2对非确定性交集使用两次:

which_icecream(DesiredIngredients, S) :-
    icecream(S, Ingredients, _),
    member(X, DesiredIngredients),
    member(X, Ingredients).

请注意,由于许多成分多次匹配,因此将多次返回相同的结果:

?- which_icecream([vanille,lemon,chocolate,mango], S).
S = number1 ;
S = number1 ;
S = number1 ;
S = number2 ;
S = number2 ;
false.

删除重复项setof/3

?- setof(S, which_icecream([vanille,lemon,chocolate,mango], S), IceCreams).
IceCreams = [number1, number2].

使用intersection/3内置的替代解决方案:

which_icecream(DesiredIngredients, S) :-
    icecream(S, Ingredients, _),
    intersection(Ingredients, DesiredIngredients, Intersection),
    Intersection \= [].

推荐阅读