I have to generate lists that consist of 2 '1's and other elements are '0's. I tried the following code but it does not work:
count([], _, 0).
count([X|T], X, Y) :- count(T, X, Z), Y is 1+Z.
count([X1|T],X,Z):- X1\=X,count(T,X,Z).
two(X) :- count(X, 1, Counter), Counter =:= 2.
Querying length(Vs, 4), Vs ins 0..1, two(Vs).
gives nothing.
How to generate such lists properly? I expect to get something like [1, 1, 0, 0], [1, 0, 1, 0] ... [0, 0, 1, 1].
twoones(Bs) :-
Bs ins 0..1,
sum(Bs, #=, 2).
?- length(Bs,4), twoones(Bs).
Bs = [_A,_B,_C,_D], clpz:(_A+_B+_C+_D#=2),
clpz:(_A in 0..1), clpz:(_B in 0..1),
clpz:(_C in 0..1), clpz:(_D in 0..1).
?- length(Bs,4), twoones(Bs), labeling([], Bs).
Bs = [0,0,1,1]
; Bs = [0,1,0,1]
; Bs = [0,1,1,0]
; ... .
Here, I am using library(clpz)
which is the successor to library(clpfd)
. For simple examples as this, there is not much of a difference.