您应该明确使用assertz/1
or asserta/1
。assert/1
是assertz/1
但仅在某些 Prolog 系统中的别名。
来电:
assertz(call(goal, X, Y)).
将尝试用 functor断言一个事实call
。这是它试图在数据库中断言的内容:
call(goal, _, _).
由于call
在 Prolog 中已经将仿函数定义为谓词,因此会产生错误。如果您要断言以下内容:
assertz(foo(goal, X, Y)).
它会成功,但是你在数据库中得到的是这样的:
foo(goal, _, _).
这似乎不是很有用。换句话说,断言只是按照你的要求做:断言你刚刚描述的一个术语,它的函子是call
或foo
在上述情况下。
如果你想断言一个实际的谓词,你只需要使用一个谓词是一个其函子是的术语:-
。一般谓词项类似于Head :- Body
或,以规范形式,':-'(Head, Body)
。可以断言这种术语,只要至少在调用Head
之前实例化即可。assertz
assertz(':-'(Head, Body)).
或等效地(因为:-
是运算符):
assertz((Head :- Body)).
如果我这样做:
Head = goal, assertz((Head :- Body)).
我得到(使用listing/0
):
:- listing.
goal :-
call(_).
不是很有用。所以Body
真的应该在进行此assertz/1
调用之前进行实例化。这是另一个例子:
Head = double(X, Y), Body = (Y is X * 2), assertz((Head :- Body)).
现在导致以下结果:
:- listing.
double(A, B) :-
B is A * 2.