Reputation: 371
I am currently working on a project that involves a matrix. I am stuck in my attempt to apply constraints to specific elements in my matrix. This is my matrix and domain definitions of the main class/predicate. So, the first 3 predicates are just creating the matrix and defining the domains while the last 2 predicates labels the different variables in regards to the domain and prints it out.
test(Solution, N) :-
length(Solution,8),
maplist(length_(8), Solution), %The variables
maplist(define_domain, Solution), %The domains
constraint(Solution),
maplist(labeling([]), Solution), %Labeling the variables
maplist(print_row, Solution).
length_(Length, List) :- length(List, Length).
define_domain(X):- X ins 0..9.
ww(X):-
write(X).
print_row(Row):-
%nested maplist call so it works on each element in the
maplist(ww, Row),
nl.
So, the constraints predicate which applies the constraint on my variables is where I am having problems. I have some facts that I need to capture so I tried using findall to loop through all the facts and use them to determine the which elements inside the list of the matrix that I need to apply the constraints to. The facts contains the row, column and length.
The nested findall predicate call uses row to determine which list inside the matrix, column to determine the index of the element of the that list to take and extracting a sublist based on the index of the element and its length. The outer findall predicate finds all the position predicates and collects all the sublists. Therefore, I have a collection of sublists contains the elements of the matrix where constraint needs to be applied. The constraint is applied in the constraint_apply predicate.
However, I discovered that the findall predicate creates copies of the original list instead of using the actual elements/variables in the original list after struggling for many hours. So, all the constraints that are being applied only affects the copies and not the originals.
Right now, I am thinking that maybe I am using the findall predicate wrongly to apply the constraints and trying out different ways to use it.
I would be grateful if someone could explain to me a better way to propagate my constraints in this scenario.Any helps/tips will be appreciated. How would you apply the constraints to the original list and elements in the matrix above?
constraint_apply([]).
constraint_apply([X|Xs]):-
sum(X, #<, 10),
all_different(X),
constraint_apply(Xs).
%Extract a slice from the lsit
constraint(Xs):-
findall(X, (position(R, C, L), End is C+L-1,
findall(Y, (nth1(R, Xs, N),between(C, End, M), nth1(M, N,Y)), X)), Row),
constraint_apply(Row).
Upvotes: 1
Views: 748
Reputation: 60034
I had a similar problem, and I solved using bagof/3 instead of findall/3. I cannot test your code, so here is just a hint to the needed syntax
constraint(Xs):-
bagof(X, R^C^L^End^(
position(R, C, L),
End is C+L-1,
bagof(Y, N^M^(nth1(R, Xs, N), between(C, End, M), nth1(M, N, Y)), X)
), Row),
constraint_apply(Row).
Upvotes: 0