Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the name of the calling predicate

Suppose I am working on this toy example (the point of the question is obviously not to solve this example):

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

call_predicate(Name,Arg) :- call(Name,Arg).

So far so good. Now let's say I want to add a predicate call_predicate/1 where I wouldn't need the name of the predicate:

call_predicate(Arg) :- Name = ??, call(Name,Arg).

So that I could use in p: call_predicate(T), implicitly knowing that I want to call the predicate of the same name.

The question is then how can I retrieve the name p from call_predicate/1, knowing that it is the name of the predicate that called call_predicate/1?

A similar question would be, if it's easier than the first one, how can I retrieve the name of the current predicate I am in at a time in the execution?

like image 788
Fatalize Avatar asked Feb 10 '16 11:02

Fatalize


1 Answers

In SWI-Prolog check out library(prolog_stack).

In particular, a combination of the following predicates should give you what you want:

  • get_prolog_backtrace/2
  • prolog_stack_frame_property/2

Beware though: This is not readily portable to other Prolog systems, and in all likelihood there are more elegant and also more efficient ways to do what you need.

For example, one way to do what you are describing is to use term_expansion/2: You can expand specific goals in such a way that one of the arguments denotes the calling context. This is much more portable, very efficient at run time, and you can statically check the resulting expansion.

like image 195
mat Avatar answered Nov 03 '22 09:11

mat