0

我一直在学习,我遇到了一个问题。我从教程中了解了 cut 运算符,但我正在尝试解决问题,但我无法理解解决方案。

问题:

如果汽车颜色是红色,意大利制造,那么它就是法拉利。如果它是红色但在德国(或任何其他国家。可能不止一个)制造,那就是奔驰。如果它不是红色的并且很大,那就是福特。不红也不大,就是丰田。

那是:

red & Italy: Ferrari
red & Germany (or not Italy): Benz
not red & big: ford
not red & not big: Toyota

给定特定汽车对象的一些事实:

color(cx, red).
speed(cx, 220).
make(cx, italy).
type(cx, sport).

我想编写一个谓词brand(X, name)来返回特定汽车对象的品牌,例如:

brand(X, ferrari):-
   color(X,red), make(X,T), T=italy.
brand(X, benz) :-
   color(X,red), not(make(X,italy)).
brand(X, ford) :-
   not(color(X,red)), size(X,big).
brand(X, toyota) :-
   not(color(X,red)), not(size(X,big)).

问题是我如何(以及在​​哪里)在这里使用 cut 运算符,以便它不会检查相同的属性(例如:这里的“make”)两次?我似乎无法解决这个问题。

如果我检查红色然后检查制造,如果制造结果不是意大利,我如何brand(X, brand_name)为汽车对象“ck”编写一组事实,使其不再检查制造?在我看来这是不可能的。

4

1 回答 1

3

简短的回答:不要

几乎总是,使用!/0会导致丢失有效的解决方案

永远记住,Prolog 程序通常比其他语言的程序更通用。特别是,请记住,用户始终可以发布最一般的查询,在您的情况下是:

?- brand(X, Y).

如果你有!/0这个定义,那么是的,你可能会“只检查一次”,但另一方面,你将无法生成所有有效的答案

一种好的方法是使用if_/3from library(reif)。例如,在您的情况下,您可以将事实写为:

颜色(cx,红色,)。
速度(cx,220,)。
制作(cx,意大利,真实)。
类型(cx,运动,)。

现在你可以写:

car_type(C,类型):-
        if_(颜色(C,红色),
            if_(make(C, italy), Type=ferrari, Type=bentz),
            if_(type(C, big), Type=ford, Type=toyota))。

重要的是,即使有多种解决方案,最通用的查询仍然有效:

?- car_type(C,类型)。
C = cx,
类型 = 法拉利。
于 2017-04-18T13:57:58.267 回答