1

我一直在阅读并注意到像call这样的谓词被称为元谓词,它们可以返回其他谓词作为结果(不知道 return 是否在这里很好地使用了这个词)例如这里:

assert(call(goal, X,Y)).

编辑:潜伏者打电话给我讲道理,这不起作用。

我知道它不应该调用谓词函数,但是有没有办法对一个直到运行时才知道的谓词进行断言?

我想对多个 fact 使用相同的插入谓词,因此 assert(fact(X)) 不适合我的需要。我可以在运行时检索事实的名称,但是如何在不直接统一事实的情况下使用断言?

4

1 回答 1

1

您应该明确使用assertz/1or asserta/1assert/1assertz/1但仅在某些 Prolog 系统中的别名。

来电:

assertz(call(goal, X, Y)).

将尝试用 functor断言一个事实call。这是它试图在数据库中断言的内容:

call(goal, _, _).

由于call在 Prolog 中已经将仿函数定义为谓词,因此会产生错误。如果您要断言以下内容:

assertz(foo(goal, X, Y)).

它会成功,但是你在数据库中得到的是这样的:

foo(goal, _, _).

这似乎不是很有用。换句话说,断言只是按照你的要求做:断言你刚刚描述的一个术语,它的函子是callfoo在上述情况下。

如果你想断言一个实际的谓词,你只需要使用一个谓词是一个其函子是的术语:-。一般谓词项类似于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.
于 2017-03-17T14:51:50.123 回答