1

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

carClass('X1','Oil','small').
carClass('X2','gas','big').
carClass('X3','Petrol','big').
carClass('X4','oil','small').
carClass('X5','Oil','small').
carClass('X6','gas','big').

我正在尝试编写一个可以回答查询的规则:显示所有在“油”上运行且不是“大”的 carClass。

我正在尝试使用以下方法实现它:

OnOilButNotBig :-
   carClass(CarClass,'oil',_),
   carClass(CarClass,'oil', \+('big') ),
   write(CarClass).

但这不起作用。

4

2 回答 2

2

您必须了解谓词函子之间的区别。

如果我们稍微简化一下,谓词是顶层carClass/3的标识符,谓词也是,是write/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两次。一个等效且效率稍高的程序如下:

onOilButNotBig :-
   carClass(CarClass,'oil',X),
   \+(X = 'big'),
   write(CarClass).

最后,正如@Repeat 所指出的,您需要使用以小写开头的名称来表示谓词和函数。

于 2016-01-03T13:28:25.793 回答
1

最重要的事情!

  • 该代码无法编译1。为什么?谓词名称通常以小写字符2开头。

    我的建议:而不是OnOilButNotBigonOilButNotBig

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

    onOilButNotBig :- 差异
       (X,大),
       汽车类(汽车类,油,_),
       汽车类(汽车类,油,X),
       写(汽车类)。
    
  • 作为旁注,您的代码还有一些问题:

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

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

      onOilButNotBig (CarClass) :-
         差异(X,大),
         汽车类(汽车类,油,_),
         汽车类(汽车类,油,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:一般来说,冗余目标是可以的,但它们向我暗示你的代码可能不会按预期运行。

于 2016-01-04T04:24:44.480 回答