【问题标题】:SWI Prolog - Using a predicate with another predicateSWI Prolog - 将谓词与另一个谓词一起使用
【发布时间】:2018-11-25 15:32:47
【问题描述】:

我对 prolog 比较陌生,我会尽力解释这一点。假设我有一个小型餐馆知识库,其中包含名称、菜式和价格。

restaurant(spaghetti, italian, 20).
restaurant('naan bread', indian, 30).
...

我有一些人喜欢某些餐厅,例如:

likes(adam, restaurant, italian).

亚当喜欢意大利餐厅的地方。我遇到的主要问题是,如果我进行如下查询:

likes(adam, spaghetti).

likes(adam, _, spaghetti).

不管我放什么,它只会出现错误。我做了很多研究,但似乎无法让它发挥作用 - 因为我对 prolog 很陌生,所以我不太了解它。我看过诸如 Clocksin 和 Mellish 的“Prolog 编程”之类的书以及各种网站,但我似乎找不到答案或我理解的答案。

【问题讨论】:

  • 你可以构造一个谓词来调用restaurantlikes这两个谓词,有点类似于JOIN在SQL中的工作方式。
  • 你从哪里得到这个问题的?是来自书本还是课堂?数据库中可能还有更多事实,您需要在此处将它们全部列出,以便我们为您提供帮助。
  • 您可能需要添加一条规则,例如likes(X, Dish) :- likes(X, restaurant, Cuisine), restaurant(Dish, Cuisine, _).Prolog 不是读心术,它无法在没有您告知的情况下判断某人喜欢某道菜,因为他们喜欢某道菜。
  • @GuyCoder 是的,它来自一个班级,但它只是一个餐馆知识库。所以没有任何其他规则。

标签: prolog


【解决方案1】:

根据您的评论

这只是一个餐馆知识库。所以没有任何其他规则。

我们将从那里开始,并从给定的规则开始。

restaurant(spaghetti, italian, 20).
restaurant('naan bread', indian, 30).

接下来是您正在尝试的查询

likes(adam, spaghetti).

这是有效的,但正如我们在 cmets 中指出的那样,缺少一些事实。

使查询正确的最简单的事实是

likes(adam, spaghetti).

但您还有其他查询,例如

likes(adam, restaurant, italian).

和诸如此类的事实

restaurant('naan bread', indian, 30).

这表明您知道adamitialianspaghetti20(价格)这四个实体之间存在关系。

建立关系的方式有很多种,但在本例中,我们将使其更加简单。

person(adam).
person(mary).

food_nationality(spaghetti, italian).
food_nationality(hamburger, americian).
food_nationality('naan bread', indian).

food_price(spaghetti, 20).
food_price(hamburger, 30).
food_price('naan bread', 30).

likes(adam,italian).
likes(mary,american).

现在我们已经掌握了一些事实,如果您想知道亚当吃他喜欢的食物要花多少钱,我们从事实开始,看看我们能得出什么结论。

我们看到了事实

person(adam).

但这只是告诉我们亚当是一个人,并没有为我们的问题提供更多信息。

我们也看到了事实

likes(adam,italian).

这告诉我们亚当喜欢意大利菜,但没有给我们特定的食物。

我们也看到了

food_nationality(spaghetti, italian).

所以我们知道亚当喜欢意大利面,而意大利面有意大利面,但我们仍然需要一个价格。

我们也看到了

food_price(spaghetti, 20).

所以我们知道亚当喜欢意大利面,而意大利面和意大利面的价格是 20 美元。所以答案是亚当吃他喜欢的东西需要 20 美元。

作为 Prolog 谓词,它会是

cost_to_eat(Person,Price) :-
   likes(Person,Nationality),
   food_nationality(Food, Nationality),
   food_price(Food, Price).

并为亚当运行它

?- cost_to_eat(adam,Price).
Price = 20.

它也适用于玛丽

?- cost_to_eat(mary,Price).
Price = 30.

如果你只给出一个价格,它也可以工作

?- cost_to_eat(Person,20).
Person = adam ;
false.

你问它也可以工作

?- cost_to_eat(Person,Cost).
Person = adam,
Cost = 20 ;
Person = mary,
Cost = 30.

【讨论】:

    【解决方案2】:

    因此,假设您有以下事实,正如您的问题中所建议的那样,没有额外的也没有变化:

    restaurant(spaghetti, italian, 20).
    restaurant('naan bread', indian, 30).
    
    likes(adam, restaurant, italian).
    

    现在你想问“亚当喜欢什么菜?”

    我们可以添加这个简单的规则:

    likes(Person, Dish) :-
        likes(Person, restaurant, Type),
        restaurant(Dish, Type, _).
    

    现在您可以继续询问以下问题:

    ?- likes(adam, Dish), write(Dish).
    

    这会吐出答案spaghetti

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-21
      • 2022-10-13
      相关资源
      最近更新 更多