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]]]
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]]]