获取调用谓词的名称

Fat*_*ize 5 reflection prolog swi-prolog

假设我正在研究这个玩具示例(问题的重点显然不是解决这个示例):

p([]).
p([H|T]) :- H = 0, call_predicate(p,T).

call_predicate(Name,Arg) :- call(Name,Arg).
Run Code Online (Sandbox Code Playgroud)

到目前为止,一切都很好。现在假设我想添加一个call_predicate/1不需要谓词名称的谓词:

call_predicate(Arg) :- Name = ??, call(Name,Arg).
Run Code Online (Sandbox Code Playgroud)

这样我就可以使用 in p: call_predicate(T),隐式地知道我想调用同名的谓词。

那么问题是,在知道这是调用的谓词的名称的情况下,如何p从 中检索名称?call_predicate/1call_predicate/1

一个类似的问题是,如果它比第一个更容易,我如何检索执行中一次所处的当前谓词的名称?

mat*_*mat 5

在 SWI-Prolog 中签出库(prolog_stack)

特别是,以下谓词的组合应该可以满足您的需求:

  • get_prolog_backtrace/2
  • prolog_stack_frame_property/2

但请注意:这不容易移植到其他 Prolog 系统,并且很可能有更优雅、更有效的方法来完成您需要的操作。

例如,执行您所描述的操作的一种方法是使用term_expansion/2:您可以通过其中一个参数表示调用上下文的方式来扩展特定目标。这更加可移植,在运行时非常高效,并且您可以静态检查生成的扩展。

  • 谢谢你的指点。我实际上想到了一种更简单的方法:由于“p”将由程序生成,我可以告诉它在“p”的开头添加“PredicateName = p”,然后将其传递给“call_predicate”。 (4认同)
  • 完美的。追求优雅和便携,并尽可能保持纯粹。 (3认同)