我有一个简单的知识数据库定义为:
carClass('X1','Oil','small').
carClass('X2','gas','big').
carClass('X3','Petrol','big').
carClass('X4','oil','small').
carClass('X5','Oil','small').
carClass('X6','gas','big').
我正在尝试编写一条能够回答查询的规则:显示在' oil'上运行的所有carClass并且不是'大'
我正在尝试使用以下方法实现它:
OnOilButNotBig :-
carClass(CarClass,'oil',_),
carClass(CarClass,'oil', \+('big') ),
write(CarClass).
但这不起作用。
答案 0 :(得分:2)
您必须了解谓词和仿函数之间的区别。
如果我们稍微过分简化,谓词是顶级的标识符,因此carClass/3
是谓词,write/1
是谓词,{{1}是的。你可以调用谓词。填充参数的谓词是目标。
另一方面,仿函数是不在顶层的标识符。 常量是仿函数,变量是仿函数,带参数的函数是仿函数。仿函数的示例包括onOilButNotBig/0
,'X1'
和'oil'
。
否定期望目标。在这种情况下,foo(X,bar,qux(2))
不是目标,事实上'big'
本身就是一个仿函数。
您只能通过将条件转换为目标来解决此问题,并确保您将其调用。这可以这样做:
\+('big')
此外,我真的不明白为什么你两次致电onOilButNotBig :-
carClass(CarClass,'oil',_),
carClass(CarClass,'oil',X),
\+(X = 'big'),
write(CarClass).
。一个等效且稍微高效的程序如下:
carClass/3
最后,正如@Repeat所述,您需要使用以小写字母开头的谓词和函数名称。
答案 1 :(得分:1)
首先要做的事情!
代码不编译 1 。 为什么?谓词名称通常以小写字符 2 开头。
我的建议:代替OnOilButNotBig
写onOilButNotBig
!
要表达术语不平等,请使用正确的prolog-dif目标,如下所示:
onOilButNotBig :- dif(X, big), carClass(CarClass, oil, _), carClass(CarClass, oil, X), write(CarClass).
作为旁注,您的代码还有一些问题:
仅在必要时使用基于副作用的I / O.
在大多数情况下,最好使用交互式prolog-toplevel进行数据输入/输出!
onOilButNotBig(CarClass) :- dif(X, big), carClass(CarClass, oil, _), carClass(CarClass, oil, X).
为了便于阅读,请不要使用'oil'
和'Oil'
等原子。
选择一个并坚持下去!我建议oil
(小写),不需要转义。
目标carClass(CarClass, oil, _)
完全多余。
为什么呢?这是近距离目标carClass(CarClass,oil,X)
的推广。
脚注1:使用b-prolog 8.1,sicstus-prolog 4.3.2,swi-prolog 7.3.14和xsb 3.6。
脚注2:如果使用右侧(使用单引号转义),名称也可以以大写字母开头。
脚注3:一般来说,冗余目标是可以的,但他们建议我的代码可能不会按预期运行。
功能