结束视图拼图,Prolog

时间:2012-05-21 14:04:14

标签: lambda prolog logic constraints clpfd

我正在尝试使用CLPFD编写End View Puzzles的解算器(对于那些不熟悉的人,这里是一个简单的描述http://www.funwithpuzzles.com/2009/12/abcd-end-view-a1.html)。我正在研究我应用于每一行/列的约束,并遇到一些麻烦。

所以我认为它应该是这样的:

% NxN board, numbers from 0 to M in the row, Left/Right are the clues
% corresponding to the row
endviews(N,M,List,Left,Right):- 
    length(List,M),
    domain(List,0,M),
    stop_repeats(List,M),
    left_value(List,M,Left),
    reverse(List,RList),
    left_value(RList,M,Right)
    .

所以前3个步骤非常简单:初始化电路板,设置域名,并确保此行不会重复0以外的数字(我已经写了{ {1}}谓词)。我遇到的问题是处理stop_repeats/2谓词;我不确定如何继续这里,因为大多数列表都没有约束,我实际上并不知道第一个正元素的位置。 任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:2)

也许automaton/3约束可以帮到这里?您可以构造一个有限自动机,它接受(可选)零,然后是指示的第一个字母,然后是零和字母的任意序列。

答案 1 :(得分:1)

我写下了拼图规范。这似乎不如你对它的描述那么通用,然后我硬编码约束,使用映射0 =空,1 = A,2 = B,3 = C.

/*  File:    abc_view.pl
    Author:  Carlo,,,
    Created: May 21 2012
    Purpose:
*/

:- module(abc_view, [abc_view/0]).
:- [library(clpfd), '~/prolog/lambda'].

abc_view :-
    maplist(\Ls^(length(Ls, 4), Ls ins 0..3), [R1,R2,R3,R4]),
    transpose([R1,R2,R3,R4], [C1,C2,C3,C4]),

    maplist(all_distinct, [R1,R2,R3,R4]),
    maplist(all_distinct, [C1,C2,C3,C4]),

    start(R2, 3),
    start(R3, 3),
    finish(R3, 2),

    start(C3, 1),
    finish(C2, 2),

    maplist(writeln, [R1,R2,R3,R4]).

finish(X, V) :-
    reverse(X, Y),
    start(Y, V).

start([0,Y|_], Y).
start([Y|_], Y).

试验:

?- abc_view.
[2,0,1,3]
[0,3,2,1]
[3,1,0,2]
[1,2,3,0]
true ;
false.

我希望你能用它来解决你的一般难题。