在prolog中转换元谓词

时间:2017-03-17 13:37:44

标签: prolog meta-predicate

我一直在阅读并注意到像调用之类的谓词被称为元谓词,他们可以返回其他谓词(不知道返回是否在这里使用了这个词)例如:

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

编辑:潜伏者叫我理智,这不起作用。

我明白它不应该调用谓词函数,但是有没有一种方法可以在谓词运行之前对谓词进行断言?

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

1 个答案:

答案 0 :(得分:1)

您应该明确使用assertz/1asserta/1assert/1assertz/1的别名,但仅限于某些Prolog系统。

电话:

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

将尝试使用仿函数call声明事实。这是它试图在数据库中断言的内容:

call(goal, _, _).

由于call是已在Prolog中定义为谓词的仿函数,因此会生成错误。如果您断言,请说明以下内容:

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

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

foo(goal, _, _).

这似乎不太有用。换句话说,断言就是按照你的要求做的:断言你刚才描述的术语,在上述情况下,其仿函数是callfoo

如果要断言实际谓词,只需要使用谓词是 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.