我目前正在开发一个涉及矩阵的项目。我一直试图将约束应用于矩阵中的特定元素。这是我的主类/谓词的矩阵和域定义。因此,前3个谓词只是创建矩阵并定义域,而最后2个谓词标记与域相关的不同变量并将其打印出来。
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.
因此,对我的变量应用约束的约束谓词是我遇到问题的地方。我有一些事实需要捕获,所以我尝试使用findall遍历所有事实并使用它们来确定我需要应用约束的矩阵列表中的哪些元素。事实包含行,列和长度。
嵌套的findall谓词调用使用row来确定矩阵内的哪个列,列用于确定要采用的列表元素的索引,并根据元素的索引及其长度提取子列表。外部findall谓词找到所有位置谓词并收集所有子列表。因此,我有一个子列表集合包含需要应用约束的矩阵元素。约束应用于constraint_apply谓词。
但是,我发现findall谓词创建原始列表的副本,而不是在经过几个小时的努力后使用原始列表中的实际元素/变量。因此,所有应用的约束只影响副本而不影响原件。
现在,我在想,也许我错误地使用findall谓词来应用约束并尝试使用不同的方法。
如果有人能够向我解释在这种情况下传播我的约束的更好方法,我将不胜感激。任何帮助/提示都将受到赞赏。您如何将约束应用于原始列表和上面矩阵中的元素?
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).
答案 0 :(得分:0)
我有类似的问题,我使用bagof / 3而不是findall / 3解决了问题。 我无法测试您的代码,所以这里只是提示所需的语法
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).