我一直在研究SkyScraper数独求解器,我想我差不多了,但我还是遇到了一个小问题。为了检查数独板的'块',我使用以下代码(因为该板不一定是9x9):
bagof(B,
R^C^(between(1, Sq, R), %R takes all values from 1 to Sq
between(1, Sq, C), %C takes all values from 1 to Sq (double for)
block(Rows, Sq, R, C, B)), %Call on block predicate,
Cells),
block(InputList, Sq, R,C, B) :-
bagof(V,
X^Y^(between(1, Sq, X), %X all values between 1 and Sq
between(1, Sq, Y), %Y all values between 1 and Sq
I is (R-1) * Sq + X, %Cycling through each 'cell' in each row up to Sq
J is (C-1) * Sq + Y,
cell(InputList, I, J, V)), %Call on cell predicate
B).
cell(InputList,R,C, V) :-
nth1(R,InputList,Row), %Get the rth row (a list)
nth1(C,Row,V).
我最初使用findall代替bagof,但我注意到它最初为R/C
和X/Y
创建了不同的变量,因此我切换到bagof并添加了{{1你可以在上面看到的C^R^
(我仍然不是 100%我确定理解其背后的原因?)。我期待这可以解决我的问题,但到目前为止,没有运气。我想我可以使用for_each而不是X^Y^
重新编写它(我相信这会解决问题),但我也想知道导致问题的原因是什么?
我确信这确实是错误发生的地方,因为返回的答案是正确的,而“盒子”不一定只包含每个数字一次。
bagof
试图约束新变量而不是传入的变量 - 它处理得很好。相反,问题在于生成单个列表的列表,而不是每个长度为K的子列表列表(对于KxK板)。当我切换到findall时,这个问题就消失了,所以我认为它与bagof的执行方式有关。以下是跟踪命令,其中包含重要的部分
使用findall进行跟踪 - 返回正确的bagof
,但新变量
block
带有bagof的%trace - 返回相同的变量,但是在单例列表中没有 %改变订单
findall(_9966,user:_9973^_9976^(between(1,2,_9973),between(1,2,_9976),block(
[[_7079,_7111,_7143,_7175],[_7270,_7302,_7334,_7366],[_7461,_7493,_7525,_7557],
[_7652,_7684,_7716,_7748]] %input list
,2,_9973,_9976,_9966)),
[[_18106,_18108,_18110,_18112],
[_18096,_18098,_18100,_18102],[_18086,_18088,_18090,_18092],
[_18076,_18078,_18080,_18082]]) ? %output list
第二次编辑:问题解决了;我忘了在 bagof(_9966,user:_9973^_9976^(between(1,2,_9973),between(1,2,_9976),block(
[[_7079,_7111,_7143,_7175],[_7270,_7302,_7334,_7366],[_7461,_7493,_7525,_7557],
[_7652,_7684,_7716,_7748]] %input list
,2,_9973,_9976,_9966)),
[[_7079],[_7111],[_7270],[_7302],
[_7143],[_7175],[_7334],[_7366],[_7461],[_7493],[_7652],[_7684],[_7525],[_7557],[_7716],
[_7748]]) ? %output list
中量化I和J;哎呦!所以该行应该改为
bagof
问题解决了:) 干杯!