简体   繁体   中英

Prolog - How can I save results from recursive calls?

I am still trying to understand the Prolog logic and have stumbled upon a problem. I am trying to save values found within recursive calls, to pass on or gather.

As such:

main([]) :- !.
main([H|Tail]) :- findall(X,something(_,_,X),R),
                  getValueReturn(R,H,Lin, Lout),
                  main(Tail).


% X is the Head from main
getValueReturn([H|Tail],X,Lin, Lout) :- subset(X, H) ->
                                findall(A,something(A,_,H),L1),
                                append(Lin,L1,Lout), 
                                getValueReturn(Tail,X,Lout,L)
                                ;
                                getValueReturn(Tail,X,Lin,Lout).  

I would like to gather the results from findall in getValueReturn, combine them, and send them back to main, which can then use them. How do I create and add to a list within getValueReturn? Similarly, how can I save the list in my main for all recursive calls?

EDIT:

I edited the code above as per a comment reply, however when I run this through trace, the list deletes all elements when the empty list is found.

What am I doing wrong? This is the first time I try to use the concept of building a list through recursion.

You should post complete code that can be run, with example data. I have not tested this.

You need to pass L around on the top-level also. Using the same variable names for different parameters in adjacent procedures does not improve readability.

main([E|Es],L0,L) :-
  findall(X,something(_,_,X),Rs),
  getValueReturn(Rs,E,L0,L1),
  main(Es,L1,L).
main([],L,L).

getValueReturn([R|Rs],E,L0,L) :-
  ( subset(E,R) ->
    findall(A,something(A,_,R),New),
    append(L0,New,L1), 
    getValueReturn(Rs,E,L1,L)
  ; getValueReturn(Rs,E,L0,L) ).
getValueReturn([],_,L,L).

A variable can only have one value in Prolog. In your code, for example, Lout is the output from append/3 , an input to a recursive call of getValueReturn/4 , and then also the output on the top-level. This is probably not going to do what you want.

I have found the best way to do what I was trying to was to use asserta/z when a result was found, and then gather these results later on.

Otherwise the code became overly complicated and did not function as intended.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM