如何使用切割操作员



我一直在学习,我遇到了一个问题。我了解教程中的剪切操作员,但我正在尝试解决问题,但我无法理解解决方案。

问题:

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

是:

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)).

问题是我在这里如何(何处(在此处使用剪切操作员,以免检查相同的属性(例如:这里"制作"(两次?我似乎无法缠绕着这个。

如果我检查了红色,然后是否要制作,如果不是意大利,我该如何为汽车对象" ck"的一组事实编写brand(X, brand_name),以免再次检查Make Make?对我来说似乎不可能。

简短答案:不要

几乎始终,使用!/0将导致丢失有效解决方案

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

?- brand(X, Y).

如果您在此定义中具有!/0,那么是的,您可能只会"检查一次",但另一方面,您将无法生成所有有效的答案

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

颜色(cx,red, true (。速度(CX,220, true (。制作(CX,意大利, true (。类型(cx,sport, true (。

现在您可以写:

car_type(c,类型(: -         if_(颜色(C,红色(,            if_(Make(C,意大利(,type = Ferrari,type = bentz(,            if_(类型(c,big(,type = ford,type = toyota((。

重要的是,即使有多种解决方案,最通用的查询也将工作:

? -  car_type(c,type(。c = cx,类型=法拉利。

最新更新