【问题标题】:Transform in meta-predicate at prolog在 prolog 中转换元谓词
【发布时间】:2017-03-17 13:37:43
【问题描述】:

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

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

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

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

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

【问题讨论】:

  • 当你说assert(call(goal, X, Y)). 会起作用是什么意思?以什么方式工作?我看到的情况是尝试断言 call(...) 会导致尝试修改现有 Prolog 过程 (call) 时出错。
  • @lurker 你说得对,我的朋友,我很累,我以为我看到了它的工作。有没有一种方法可以在事先不知道断言需要哪个谓词的情况下进行断言?我会修改我的问题。对不起
  • 不用担心。关于手头的问题:谓词只是一个 term 对吗?它看起来像':-'(head, body)。所以你可以做assertz(':-'(Head, Body)).,其中HeadBody 在运行时被实例化。您也可以将其写为assertz((Head :- Body)).,因为:- 是一个运算符。请注意,HeadBody 应在调用 assertz/1 时进行实例化。
  • Lurker,我会试试你的方法,我真的很喜欢这种语言。感谢您的意见,这肯定有助于进步。

标签: prolog meta-predicate


【解决方案1】:

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

电话:

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

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

call(goal, _, _).

由于call 是一个已经在Prolog 中定义为谓词的函子,它会产生错误。如果您要断言以下内容:

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

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

foo(goal, _, _).

这似乎不是很有用。换句话说,断言只是按照您的要求执行:断言您刚刚描述的 term,在上述情况下,其函子是 callfoo

如果你想断言一个实际的谓词,你只需要使用一个谓词是一个 term 的事实,它的函子是:-。一般谓词术语类似于Head :- Body 或规范形式':-'(Head, Body)。只要在assertz 调用之前至少实例化了Head,就可以断言这种术语。

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.

【讨论】:

  • 一如既往,很好的解释和重点。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多