prolog查询中的否定不起作用

时间:2016-01-03 12:59:35

标签: prolog logic negation

我有一个简单的知识数据库定义为:

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

但这不起作用。

2 个答案:

答案 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 开头。

    我的建议:代替OnOilButNotBigonOilButNotBig

  • 要表达术语不平等,请使用正确的目标,如下所示:

    onOilButNotBig :-
       dif(X, big),
       carClass(CarClass, oil, _),
       carClass(CarClass, oil, X),
       write(CarClass).
    
  • 作为旁注,您的代码还有一些问题:

    1. 仅在必要时使用基于副作用的I / O.

      在大多数情况下,最好使用交互式进行数据输入/输出!

      onOilButNotBig(CarClass) :-
         dif(X, big),
         carClass(CarClass, oil, _),
         carClass(CarClass, oil, X).
      
    2. 为了便于阅读,请不要使用'oil''Oil'等原子。

      选择一个并坚持下去!我建议oil(小写),不需要转义。

    3. 目标carClass(CarClass, oil, _) 完全多余。

      为什么呢?这是近距离目标carClass(CarClass,oil,X)的推广。

脚注1:使用 8.1, 4.3.2, 7.3.14和 3.6。
脚注2:如果使用右侧(使用单引号转义),名称​​也可以以大写字母开头。
脚注3:一般来说,冗余目标是可以的,但他们建议我的代码可能不会按预期运行。 功能