prologprolog-findall

Prolog problem with findall how to construct a solution of a list which is a pair (element, list_of_elements)


I'm trying to resolve a problem but I don't know how to manage properly the predicate findall.

The idea is the next one.

We have a table and some blocks arranged in a stack on the table.

This could be a example of a given situation: Table->a,b,c,d

So the block a, is exactly on the table, the block b on the block a, and so on.

We have also, some predicates like the next:

stacking(X,Y):-
    over(X,Y).

stacking(X,Y):-
    over(X,Z),
    stacking(Z,Y).

just_over_table(X).

Thus, the predicate stacking(X,Y) indicates that a block "X" is stacking over a block Y, not necessarily exactly over it, but X is in a "superior level". For example, in the stack table->abcd d is stacking over b.

Other predicate is over(X,Y) that predicate indicates that a block X is exactly over the block Y, an example could be, table->abcd, the block c it's over block b.

The problem it's to write a new predicate, called solution(L), L is a list that contains all lists of pairs [B,LB] where B is a block of the stack with a minimum of 2 blocks under it, excluding block exactly over the table (in the example table->abcd, a is exactly over the table, b,c,d are not). LB is a list that contains the blocks that are under B in the stack. If there aren't any block that accomplish the conditions, L should be returned empty.

For do this problem, we can use this knowledge as example:

over(d,c).
over(c,b).
over(b,a).

just_over_table(a).

My idea to solve the problem is the next code:

solution(L):-
    findall([B,LB],(stacking(B,X),stacking(X,Y),X\==Y, \+ just_over_table(Y)),L).

The problem I've found, it's I don't know how to insert X and Y in the list LB.

For the example of table->abcd

The solution should be L=[[d,[c,b]]]


Solution

  • Supposing your code works as expected, the solution is straightforward: instead of

    solution(L):-
        findall([B,LB],(stacking(B,X),stacking(X,Y),X\==Y, \+ just_over_table(Y)),L).
    

    just write

    solution(L):-
        findall([B,[X,Y]],(stacking(B,X),stacking(X,Y),X\==Y, \+ just_over_table(Y)),L).
    

    So simply replace LB with [X,Y].

    ?- solution(L).
    L = [[d, [c, b]]]