I am trying to generate pieces on a board at specific positions. One requirement is no two pieces can occupy the same position. So the board as a list, cannot contain duplicate entries for it's position value.
I failed to remove the duplicates in generation part, otherwise it correctly fails on duplicates if I ask it explicitly.
role(k).
role(r).
color(w).
color(b).
piece(X-Y) :- color(X), role(Y).
piese(X-Y) :- piece(X), pos_(Y).
piese_pos(X, Y) :- X=_-_-Y.
board(Ps) :- maplist(piese_pos, Ps, Ls), is_set(Ls), maplist(piese, Ps).
pos_(a-1).
pos_(a-2).
/*
When I ask board board(X). This is one of the enumerations:
X = [w-k-(a-1), b-k-(a-2), w-r-(a-2)] ;
as you can see a-2 is duplicated.
But if I ask for a duplicate explicitly, it returns false as correct.
[11] ?- board([w-k-(a-1), b-r-(a-1)]).
false.
[11] ?- board([w-k-(a-1), b-r-(a-2)]).
true.
*/
% https://stackoverflow.com/a/9007359/3994249
is_set(Lst) :-
setof(X, member(X, Lst), Set),
length(Lst, N),
length(Set, N).
Assuming that every position on the board must have a piece, you can generate boards with the following code:
board(Ps) :-
setof(P, pos_(P), Ls),
maplist(piese_pos, Ps, Ls),
maplist(piese, Ps).
Example:
?- board(Ps).
Ps = [w-k-(a-1), w-k-(a-2)] ;
Ps = [w-k-(a-1), w-r-(a-2)] ;
Ps = [w-k-(a-1), b-k-(a-2)] ;
Ps = [w-k-(a-1), b-r-(a-2)] ;
Ps = [w-r-(a-1), w-k-(a-2)] ;
Ps = [w-r-(a-1), w-r-(a-2)] ;
Ps = [w-r-(a-1), b-k-(a-2)] ;
Ps = [w-r-(a-1), b-r-(a-2)] ;
Ps = [b-k-(a-1), w-k-(a-2)] ;
Ps = [b-k-(a-1), w-r-(a-2)] ;
Ps = [b-k-(a-1), b-k-(a-2)] ;
Ps = [b-k-(a-1), b-r-(a-2)] ;
Ps = [b-r-(a-1), w-k-(a-2)] ;
Ps = [b-r-(a-1), w-r-(a-2)] ;
Ps = [b-r-(a-1), b-k-(a-2)] ;
Ps = [b-r-(a-1), b-r-(a-2)].
Otherwise, you can use this other definition:
board(Ps) :-
setof(P, pos_(P), S),
set_subset(S, Ls),
maplist(piese_pos, Ps, Ls),
maplist(piese, Ps).
set_subset([], []).
set_subset([X|Xs], S) :-
set_subset(Xs, T),
( S = T
; S = [X|T] ).
Example:
?- board(Ps).
Ps = [] ;
Ps = [w-k-(a-1)] ;
Ps = [w-r-(a-1)] ;
Ps = [b-k-(a-1)] ;
Ps = [b-r-(a-1)] ;
Ps = [w-k-(a-2)] ;
Ps = [w-r-(a-2)] ;
Ps = [b-k-(a-2)] ;
Ps = [b-r-(a-2)] ;
Ps = [w-k-(a-1), w-k-(a-2)] ;
Ps = [w-k-(a-1), w-r-(a-2)] ;
Ps = [w-k-(a-1), b-k-(a-2)] ;
Ps = [w-k-(a-1), b-r-(a-2)] ;
Ps = [w-r-(a-1), w-k-(a-2)] ;
Ps = [w-r-(a-1), w-r-(a-2)] ;
Ps = [w-r-(a-1), b-k-(a-2)] ;
Ps = [w-r-(a-1), b-r-(a-2)] ;
Ps = [b-k-(a-1), w-k-(a-2)] ;
Ps = [b-k-(a-1), w-r-(a-2)] ;
Ps = [b-k-(a-1), b-k-(a-2)] ;
Ps = [b-k-(a-1), b-r-(a-2)] ;
Ps = [b-r-(a-1), w-k-(a-2)] ;
Ps = [b-r-(a-1), w-r-(a-2)] ;
Ps = [b-r-(a-1), b-k-(a-2)] ;
Ps = [b-r-(a-1), b-r-(a-2)].