Prolog 将约束应用于矩阵中的原始列表项

Prolog Applying Constraints to Original List Items in Matrix

我目前正在从事一个涉及矩阵的项目。我一直在尝试对矩阵中的特定元素应用约束。这是我主要class/predicate的矩阵和域定义。因此,前 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 谓词调用使用行来确定矩阵中的哪个列表,使用列来确定要采用的该列表的元素的索引,并根据元素的索引及其长度提取子列表。外部 findall 谓词查找所有位置谓词并收集所有子列表。因此,我有一个子列表集合,其中包含需要应用约束的矩阵元素。约束应用于 constraint_apply 谓词。

然而,我发现 findall 谓词创建了原始列表的副本,而不是使用原始列表中的实际 elements/variables 经过数小时的努力。因此,所有应用的约束只影响副本而不影响原件。

现在,我在想,也许我错误地使用了 findall 谓词来应用约束并尝试了不同的使用方式。

如果有人能向我解释一种更好的方法来传播我在此 scenario.Any helps/tips 中的约束,我将不胜感激。您将如何将约束应用于上面矩阵中的原始列表和元素?

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).

我遇到了类似的问题,我用 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).