序言查询中的否定不起作用
Negation in prolog query is not working
嗨,我有一个简单的知识数据库定义为:
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' 上运行且不是 'big'.[= 的所有 carClass 12=]
我正在尝试使用以下方法实现它:
OnOilButNotBig :-
carClass(CarClass,'oil',_),
carClass(CarClass,'oil', \+('big') ),
write(CarClass).
但这不起作用。
你必须理解 predicate 和 functor.
之间的区别
如果我们把事情简单化一点,谓词是一个标识符在顶层,所以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).
最后,如 所述,您需要为谓词和函数使用以小写字母开头的名称。
要事第一!
代码无法编译1。
为什么?谓词名称通常以小写字母开头2.
我的建议:将 <b>On</b>OilButNotBig
写成 <b>on</b>OilButNotBig
!
要表达术语不平等,请使用正确的 prolog-dif 目标,如下所示:
onOilButNotBig :-
dif(X, big),
carClass(CarClass, oil, _),
carClass(CarClass, oil, X),
write(CarClass).
附带说明一下,您的代码还有一些问题:
仅在必要时使用基于side-effect的I/O。
在大多数情况下,最好对数据使用交互式 prolog-toplevel input/output!
onOilButNotBig(CarClass) :-
dif(X, big),
carClass(CarClass, oil, _),
carClass(CarClass, oil, X).
为了可读性,请不要使用像'oil'
和'Oil'
这样的原子。
选择一个并坚持下去!我建议不需要转义的oil
(小写)。
目标 carClass(CarClass, oil, _)
完全 多余。
为什么?它是 close-by 目标 carClass(CarClass,oil,<b>X</b>)
.
[=75= 的概括]
脚注 1: 使用时 b-prolog 8.1, sicstus-prolog 4.3.2, swi-prolog 7.3.14, and xsb 3.6。
脚注 2: 名称 可以 如果使用右(使用 single-quotes 转义)也可以以大写字符开头。
脚注 3: 一般来说,冗余目标是可以的,但它们向我暗示您的代码可能不会按预期运行。
嗨,我有一个简单的知识数据库定义为:
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' 上运行且不是 'big'.[= 的所有 carClass 12=]
我正在尝试使用以下方法实现它:
OnOilButNotBig :-
carClass(CarClass,'oil',_),
carClass(CarClass,'oil', \+('big') ),
write(CarClass).
但这不起作用。
你必须理解 predicate 和 functor.
之间的区别如果我们把事情简单化一点,谓词是一个标识符在顶层,所以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).
最后,如
要事第一!
代码无法编译1。 为什么?谓词名称通常以小写字母开头2.
我的建议:将
<b>On</b>OilButNotBig
写成<b>on</b>OilButNotBig
!要表达术语不平等,请使用正确的 prolog-dif 目标,如下所示:
onOilButNotBig :- dif(X, big), carClass(CarClass, oil, _), carClass(CarClass, oil, X), write(CarClass).
附带说明一下,您的代码还有一些问题:
仅在必要时使用基于side-effect的I/O。
在大多数情况下,最好对数据使用交互式 prolog-toplevel input/output!
onOilButNotBig(CarClass) :- dif(X, big), carClass(CarClass, oil, _), carClass(CarClass, oil, X).
为了可读性,请不要使用像
'oil'
和'Oil'
这样的原子。选择一个并坚持下去!我建议不需要转义的
oil
(小写)。目标
carClass(CarClass, oil, _)
完全 多余。为什么?它是 close-by 目标
[=75= 的概括]carClass(CarClass,oil,<b>X</b>)
.
脚注 1: 使用时 b-prolog 8.1, sicstus-prolog 4.3.2, swi-prolog 7.3.14, and xsb 3.6。
脚注 2: 名称 可以 如果使用右(使用 single-quotes 转义)也可以以大写字符开头。
脚注 3: 一般来说,冗余目标是可以的,但它们向我暗示您的代码可能不会按预期运行。