在序言中转换元谓词
Transform in meta-predicate at prolog
我一直在阅读并注意到像 call 这样的谓词被称为元谓词,因此它们可以 return 其他谓词(不知道是否 return 在这里很好地使用了这个词)例如这里:
assert(call(goal, X,Y)).
编辑:潜伏者叫我推理,这行不通。
我知道它不应该调用谓词函数,但是有没有一种方法可以对直到运行时才知道的谓词进行断言?
我想对多个事实使用同一个插入谓词,所以 assert(fact(X)) 不适合我的需要。我可以在运行时检索事实的名称,但我如何在不直接统一事实的情况下使用断言?
您应该明确使用 assertz/1
或 asserta/1
。 assert/1
是 assertz/1
的别名,但仅在某些 Prolog 系统中。
来电:
assertz(call(goal, X, Y)).
将尝试用函子 call
断言 事实 。这是它试图在数据库中断言的内容:
call(goal, _, _).
因为call
是一个已经在Prolog 中定义为谓词的仿函数,它会产生一个错误。例如,如果您要断言以下内容:
assertz(foo(goal, X, Y)).
它会成功,但是你在数据库中得到的是这样的:
foo(goal, _, _).
这似乎不是很有用。换句话说,断言只是按照您的要求进行:断言您刚刚描述的 term 在上述情况下其仿函数是 call
或 foo
。
如果你想断言一个实际的谓词,你只需要使用谓词是一个 term 的事实,其函子是 :-
。一般谓词术语类似于 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.
我一直在阅读并注意到像 call 这样的谓词被称为元谓词,因此它们可以 return 其他谓词(不知道是否 return 在这里很好地使用了这个词)例如这里:
assert(call(goal, X,Y)).
编辑:潜伏者叫我推理,这行不通。
我知道它不应该调用谓词函数,但是有没有一种方法可以对直到运行时才知道的谓词进行断言?
我想对多个事实使用同一个插入谓词,所以 assert(fact(X)) 不适合我的需要。我可以在运行时检索事实的名称,但我如何在不直接统一事实的情况下使用断言?
您应该明确使用 assertz/1
或 asserta/1
。 assert/1
是 assertz/1
的别名,但仅在某些 Prolog 系统中。
来电:
assertz(call(goal, X, Y)).
将尝试用函子 call
断言 事实 。这是它试图在数据库中断言的内容:
call(goal, _, _).
因为call
是一个已经在Prolog 中定义为谓词的仿函数,它会产生一个错误。例如,如果您要断言以下内容:
assertz(foo(goal, X, Y)).
它会成功,但是你在数据库中得到的是这样的:
foo(goal, _, _).
这似乎不是很有用。换句话说,断言只是按照您的要求进行:断言您刚刚描述的 term 在上述情况下其仿函数是 call
或 foo
。
如果你想断言一个实际的谓词,你只需要使用谓词是一个 term 的事实,其函子是 :-
。一般谓词术语类似于 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.