Add elements dynamically to an initially empty list recursively

I’m using: SWI-Prolog version 8

I want the code to:

Add element one by one dynamically to an initially empty list recursively

But what I’m getting is:

In my response i have just the last element

My code looks like this:

addelement(E,List,[E|List]).

doCallProve(P,0,PResult).

doCallP(P,N,PResult):-
    call(P,R),
    %append([],R,PResult),
    addelement(R,List,ProveResult),
    doCallProve(P,N1,PResult),
    N is N1 + 1.

Can you give us the input, the expected output and I suspect you are getting an error, so the error you are getting.

I have no error it is I can not add in an empty list at the start the result of the call (P, R) that I store in R I would like to each call put the R in a list

Since I don’t know how to construct the particular P and R for your code, here is something that I hope is similar enough to your need that will help.

sum_list([H|T],R) :-
    sum_list(T,R0),
    plus(H,R0,R).
sum_list([],0).

Examples

?- sum_list([],R).
R = 0.

?- sum_list([1],R).
R = 1.

?- sum_list([1,2],R).
R = 3.

?- call(sum_list,[],R).
R = 0.

?- call(sum_list,[1],R).
R = 1.

?- call(sum_list,[1,2],R).
R = 3.

Based on the predicate name doCallProve this looks like you could be trying to do proofs with Prolog. In the that case you might want to switch from the default reasoning of backward chaining in Prolog to forward chaining.

See:
Pfc – a package for forward chaining in Prolog
Pfc pack (forward chaining) – can’t get to work

HTH

Please show how you load and run your code, what you expect to see, and what you get instead. Explain how what you expect is different from what you get.

When you find a moment, you might want to check out this very nice article:

“How to create a Minimal, Reproducible example”. Obviously we are not at Stackoverflow but the article is helpful in many contexts.

3 posts were merged into an existing topic: Wiki Discussion: Minimal and reproducible working examples

Thanks for your proposal , when I run the program I print in the console the result of the call(P,R),
R is a array it’s looks like :

[xx(x(yy)),xx(yy),xx(yy),nott((yy)),tt(yy),tt(yy),z3(yy)]

Now I want to put the R in a List for every execution. If you see my code I have a counter N. We execute call(P,R) N times and I don’t need to sum the elements, I need to push R in a List for example

[[xx(tt(yy)),tt(yy),tt(yy),xx(tt(yy)),tt(yy),tt(yy),z3(yy)],[[xx(tt(yy)),tt(yy),tt(yy),z3(yy)]].

I have some restriction .

This is too difficult to understand, sorry. Maybe someone else can help.

addelement(E,List,[E|List]).

doCallProve(Prove,0,ProveResult).

doCallProve(P,N,PResult):-
    call(P,D),
    addelement(D,[],PResult),
    printDelta(D),
    doCallProve(P,N1,PResult),
    N is N1 + 1.

I doCallProve in another Predicate I gave the value of P for example P value = prove([accept(call)])
and when we run i have a response looks like [xx(ttt(yy)),tt(yy),tt(yy)]
at the first time if now I need to push this response in List the predicate doCallProve is running N times I need to put for each times the response in a List

At the End my List should like to List = [[xx(ttt(yy)),tt(yy),tt(yy)],[xx(ttt(yy)),tt(yy),tt(yy)],[xx(ttt(yy)),tt(yy),tt(yy)]] if doCallProve is executed 3 times

That was understood. :slightly_smiling_face:

As Boris has noted (How to create a Minimal, Reproducible Example) and I have noted ( Minimal and reproducible working examples), would help us.

We do want to help but don’t want to be doing all of the work.

Does this help?

data(1,['Monday','Tuesday','Wednesday']).
data(2,['Red','Orange','Yellow']).
data(3,[true,false]).

doCallData(Prop, N, Result) :-
   length(Result, N),
   maplist(Prop, Result).

e.g.

?- doCallData(data(2),3,Result).
Result = [['Red', 'Orange', 'Yellow'], ['Red', 'Orange', 'Yellow'], ['Red', 'Orange', 'Yellow']].

Thank you this is the principle in fact the result is what I would like to know the data comes from the response of the call in my case in the variable D and initially the list is empty

Minimal Example .

Actually when I doCallprove a have a result like this ['mongo,'anas']

Now I want to call a predicate(addelemrnt) in doCallprove who permit to add each result in a List

Finally I should have [['mongo','ananas'],['orange','apple']]

addelement(E,List,[E|List]).

doCallProve(P,PResult).

doCallP(P,N,PResult):-
    call(P,R),
    addelement(R,[],PResult), % permit to add each result in the List
    doCallProve(P,PResult).

The addelement don’t work we just return the last because the variable List is empty how accumulate element in the List predicate docallProve is called by another predicate . I hope it’s more clear.

Not really.

Your problem seems to be with just the predicate addelement so a minimal example would have only that predicate. doCallP and doCallProve should not be in the minimal example.

If I understand this then you need a predicate which you call addelement should start with an empty list and then add one element and return a new list, e.g.

?- append([],[a],R).
R = [a].

start with a non empty list and then add one element and return a new list, e.g.

?- append([a],[b],R).
R = [a, b].

So with your data then

?- append([],[['mongo','ananas']],R).
R = [[mongo, ananas]].

?- append([['mongo','ananas']],[['orange','apple']],R).
R = [[mongo, ananas], [orange, apple]].

If that is correct then you should use the builtin predicate append/3 as demonstrated. Also since the data is list of list, that can be confusing. Try learning to use append with just simple list then once that makes sense do the problem with list of list.

Take care to note that with append/3 all the values need to be list. If one of the values is just an element it will not work.

?- append(a,[b],R).
false.

The first element needs to be converted to a list by converting it to a list with [ ], e.g.

?- append([a],[b],R).
R = [a, b].

HTH

Thank you, that’s what I’m currently trying to do :If I understand this then you need a predicate which you call addelement should start with an empty list and then add one element and return a new list,

I wasn’t sure if you knew how to write addelement as you needed so created this

add_element(Element,List0,List) :-
    atomic(Element),
    is_list(List0),
    append([Element],List0,List).
add_element(List0,List1,List) :-
    is_list(List0),
    is_list(List1),
    append(List0,List1,List).

:- begin_tests(add_element).

test_case(success,[],[],[]).
test_case(success,[a],[],[a]).
test_case(success,[],[a],[a]).
test_case(success,[a],[b],[a,b]).

test_case(fail,a,b).
test_case(fail,[],a).

test(1,[forall(test_case(success,A,B,C))]) :-
    add_element(A,B,C).

test(1,[fail,forall(test_case(fail,A,B))]) :-
    add_element(A,B,_).

:- end_tests(add_element).

To run the test cases after you consult the file with the source.

?- run_tests.
% PL-Unit: add_element ...... done
% All 6 tests passed
true.