1

Suppose we have a predicate p/2 that does something similar to this:

p('an atom', OutputList) :-
  some_predicate_1,
  some_predicate_2,
  ...
  findall(...,...,OutputList).

p/2 does something arbitrarly complex and in the end put some result in OutputList.

Suppose I need to have the body of the predicate p/2 in a list: Body = [some_predicate_1,...,findall(...,...,OutputList)] and I want to execute it.

If I do something like call(Body), how can I retrieve OutputList?

Is there any other predicate I can use?

Maybe call/1 or call/2 are not right for this purpose.

repeat
  • 18,496
  • 4
  • 54
  • 166
Kami
  • 1,079
  • 2
  • 13
  • 28
  • 2
    Easy to do: In addition to the list of goals, also keep track of the variable so that you can easily refer to it. For example, use a pair like `OutputList-[some_predicate_1,...,findall(...,...,OutputList)]`. Then, after `maplist(call, Ls)` (where `Ls` is the second part of this pair, i.e., the list of goals), you can refer to `OutputList`, which is easily available as the first term of the pair. This is a quite general solution for such problems. You only need to keep track of the variables you want to refer to later. Notice the similarity of such structures to actual Prolog rules by the way! – mat Oct 14 '15 at 11:51
  • Thanks, but I am not sure I can do that. I have to use the variable Body like call(Body). I can not istantiate it to its actual predicates because they can be arbitrary. – Kami Oct 14 '15 at 12:33
  • 1
    No matter, you can still use a pair like `OutputList-Body`, and after `call(Body)`, you can refer to `OutputList`. However, I strongly recommend a clean representation as a *list of goals*, which is also what you indicate in your question. In your question, `Body` is a *list*, and you call these goals for example with `maplist(call, Goals)`. This is a much better representation, because it is not defaulty. – mat Oct 14 '15 at 13:26

1 Answers1

0

could be easy as

get_output_list(Predicates, Outputlist) :-
  last(Predicates, findall(_,_,Outputlist)),
  maplist(call, Predicates).

if findall/3 isn't always the last one, this should work

get_output_list(Predicates, Outputlist) :-
  maplist(call, Predicates),
  member(findall(_,_,Outputlist), Predicates).

in case there could be more than one findall in Predicates, placing member/2 after maplist/2 will get all Outputlist on backtracking

CapelliC
  • 59,646
  • 5
  • 47
  • 90
  • Thanks, but I can not make the assumption that the result is given always as the last clause. – Kami Oct 14 '15 at 12:23
  • Thank you again. Almost, the result is not bound to be in a findall though, but it is always the second parameter of the head of the rule p/2. I could get that with clause/2, but I do not know how to bound it with OutputList after I have executed all the predicates in the body (also I have Body as a variable, it is not bound with its actual predicates because they can differ and I can not predict the structure in advance). – Kami Oct 14 '15 at 12:37
  • clause/2 doesn't seems really appropriate... maybe you should clarify further what you expect. Doesn't seems to match with your question. – CapelliC Oct 14 '15 at 12:49