用谓词求解prolog中的kakuro

用谓词求解prolog中的kakuro,prolog,Prolog,我想解决卡库罗问题。 我的卡库罗就是这个 我必须使用单词solve(solve/1)为游戏kakuro创建一个谓词。我尝试了3-4个代码,但都有错误。变量必须在1-9之间(值在1-9之间),并且所有变量必须在一行和一列中不同(24=A+B+C而不是24=A+A+C) 第一个代码是: :- use_module(library(clpfd)). solve(L):- L= [A,B,C,E,F,G,J,K,L,N,O,P], all_different(L), L ins

我想解决卡库罗问题。
我的卡库罗就是这个

我必须使用单词solve(solve/1)为游戏kakuro创建一个谓词。我尝试了3-4个代码,但都有错误。变量必须在1-9之间(值在1-9之间),并且所有变量必须在一行和一列中不同(24=A+B+C而不是24=A+A+C)

第一个代码是:

:- use_module(library(clpfd)).
solve(L):-
    L= [A,B,C,E,F,G,J,K,L,N,O,P],
    all_different(L),
   L ins 1..9,
    A #= 24-B-C,
    B #= 26-F-J-N,
    C #= 15-G-K-O,
    E #= 11-F-G,
    E #= 17-A,
    J #= 22-K-L,
    N #= 14-O-P,
    L #= 13-P.
第二个代码:

:- use_module(library(clpfd)).
sum_list([],0).
sum_list([Head|Tail], Sum):-sum_list(Tail, Sum1),Sum is Head+Sum1.

go:-
    Vars=[A,B,C,E,F,G,J,K,L,N,O,P],
    Vars ins 1..9,
    word([A,B,C],24),
    word([B,F,J,N],26),
    word([C,G,K,O],15), 
    word([E,F,G],11),
    word([A,E],17),
    word([J,K,L],22),
    word([N,O,P],14),   
    word([L,P],13),
    labeling(Vars),
    writeln(Vars).

word(L,Sum):-
sum_list(L,X),
X=:=Sum,
all_different(L).
第三个代码:

:- use_module(library(clpfd)).
 kakuro(L):-
      L = [A,B,C,E,F,G,J,K,L,N,O,P],
      L ins 1..9,       
      Z1 = [A,B,C],
      all_different(Z1),
      A =:= 24-B-C,     
      Z2 = [B,F,J,N],
      all_different(Z2),
      B =:=26-F-J-N,
      Z3 = [C,G,K,O],
      all_different(Z3),
      C =:= 15-G-K-O,
      Z4 = [E,F,G],
      all_different(Z4),
      E =:= 11-F-G,
      Z5 = [A,E],
      all_different(Z5),
      E =:= 17-A,
      Z6 = [J,K,L],
      all_different(Z6),
      J =:=22-K-L,
      A1 = [N,O,P],
      all_different(A1),
      N =:= 14-O-P,
      A2 = [L,P],
      all_different(A2),
      L =:=13-P,
      labeling([], L).
还有,我如何开始解决过程?它会像:
?-solve(L)。
??此外,1..9中的
L也不工作。

首先,在修复
ins
/
标签问题之前:您的代码#1和#3存在问题。在代码#1中,您声明所有变量都需要有不同的值。这将无法提供有效的解决方案。在代码#1和#3中,您使用变量
L
一次作为变量的容器,一次作为一个元素

我已经用测试工具测试了我的代码。代码如下:

:- use_module(library(clpfd)).

sum_list([],0).
sum_list([Head|Tail], Sum):-
    sum_list(Tail, Sum1),
    Sum is Head+Sum1.

kakuro(Vars):-
    Vars=[A,B,C,E,F,G,J,K,L,N,O,P],
    Vars ins 1..9,
    word([A,B,C],24), 
    word([B,F,J,N],26),
    word([C,G,K,O],15), 
    word([E,F,G],11),
    word([A,E],17),
    word([J,K,L],22),
    word([N,O,P],14),   
    word([L,P],13),
    writeln(Vars).

word(L,Sum):-
    labeling([],L),
    all_different(L),
    sum_list(L,Sum).
这是
?-kakuro(L)的(唯一)输出。


首先,您需要运行
ins/2
谓词。这应该适用于SWI prolog。其次,您知道如何使用
标记/2
谓词。这将设置从其域(通过
ins/2
)到条目的给定值。在SWI Prolog中,第一个属性是选项列表,无需担心标记变量后,您可以“测试”变量并对其施加约束。您可以在开始时为所有变量做一次标记,但这相当缓慢,因为您的所有进度都丢失了。因此,我建议在
word/2
谓词中执行此操作。如果出现死胡同,回溯将返回到
word/2
谓词,而不是
kakuro/1
谓词的开头。

首先,在修复
ins
/
标签问题之前:您的代码#1和#3存在问题。在代码#1中,您声明所有变量都需要有不同的值。这将无法提供有效的解决方案。在代码#1和#3中,您使用变量
L
一次作为变量的容器,一次作为一个元素

我已经用测试工具测试了我的代码。代码如下:

:- use_module(library(clpfd)).

sum_list([],0).
sum_list([Head|Tail], Sum):-
    sum_list(Tail, Sum1),
    Sum is Head+Sum1.

kakuro(Vars):-
    Vars=[A,B,C,E,F,G,J,K,L,N,O,P],
    Vars ins 1..9,
    word([A,B,C],24), 
    word([B,F,J,N],26),
    word([C,G,K,O],15), 
    word([E,F,G],11),
    word([A,E],17),
    word([J,K,L],22),
    word([N,O,P],14),   
    word([L,P],13),
    writeln(Vars).

word(L,Sum):-
    labeling([],L),
    all_different(L),
    sum_list(L,Sum).
这是
?-kakuro(L)的(唯一)输出。


首先,您需要运行
ins/2
谓词。这应该适用于SWI prolog。其次,您知道如何使用
标记/2
谓词。这将设置从其域(通过
ins/2
)到条目的给定值。在SWI Prolog中,第一个属性是选项列表,无需担心标记变量后,您可以“测试”变量并对其施加约束。您可以在开始时为所有变量做一次标记,但这相当缓慢,因为您的所有进度都丢失了。因此,我建议在
word/2
谓词中执行此操作。如果出现死胡同,回溯将返回到
word/2
谓词,而不是
kakuro/1
谓词的开头。

以下是基于DuDa的解决方案,但使用
sum/3
约束并将标记延迟到结尾。这使得解决方案更高效、更具声明性

:- use_module(library(clpfd)).

kakuro(Vars):-
    Vars=[A,B,C,E,F,G,J,K,L,N,O,P],
    Vars ins 1..9,
    word([A,B,C],24), 
    word([B,F,J,N],26),
    word([C,G,K,O],15), 
    word([E,F,G],11),
    word([A,E],17),
    word([J,K,L],22),
    word([N,O,P],14),   
    word([L,P],13),
    labeling([],Vars).

word(L,Sum):-
    all_different(L),
    sum(L,#=,Sum).

以下是基于DuDa的解决方案,但使用了
sum/3
约束并将标签延迟到最后。这使得解决方案更高效、更具声明性

:- use_module(library(clpfd)).

kakuro(Vars):-
    Vars=[A,B,C,E,F,G,J,K,L,N,O,P],
    Vars ins 1..9,
    word([A,B,C],24), 
    word([B,F,J,N],26),
    word([C,G,K,O],15), 
    word([E,F,G],11),
    word([A,E],17),
    word([J,K,L],22),
    word([N,O,P],14),   
    word([L,P],13),
    labeling([],Vars).

word(L,Sum):-
    all_different(L),
    sum(L,#=,Sum).

@马克斯,我上传了卡库罗的照片,我必须解决。我必须写一个约束解/1,它给出了kakuro的解。。我有以下条件:1)变量在行或列中必须不同2)数字(A=:=24-B-C)必须在1-9之间(比如A必须只有1或2…等等)@MaxB我尝试了我上面写的代码,但是当我运行它时,我得到了很多错误。第三个版本似乎接近正确,但是你应该使用操作符
#=
,而不是
=:=
(就像在你的第一个版本中一样)。
Xs ins 1..9
可能不能在所有版本的clpfd中工作,这取决于你使用的是哪个prolog系统。例如,SICStus定义了
域(Xs,1,9)
。@jnmonette当我使用#=不起作用时,我有更多的错误。。我还应该如何调用谓词kakuro?我试过“?-kakuro([A,B,C,E,F,G,J,K,L,N,O,P])”我的错误是:错误未知程序:卡库罗/1(DWIM无法纠正目标)。。。如果我问你呢?-卡库罗。还是?-卡库罗(左)。或者?-卡库罗([L])或者?-卡库罗。都一样error@MaxB,我上传了我要解决的卡库罗的照片。我必须写一个约束解/1,它给出了kakuro的解。。我有以下条件:1)变量在行或列中必须不同2)数字(A=:=24-B-C)必须在1-9之间(比如A必须只有1或2…等等)@MaxB我尝试了我上面写的代码,但是当我运行它时,我得到了很多错误。第三个版本似乎接近正确,但是你应该使用操作符
#=
,而不是
=:=
(就像在你的第一个版本中一样)。
Xs ins 1..9
可能不能在所有版本的clpfd中工作,这取决于你使用的是哪个prolog系统。例如,SICStus定义了
域(Xs,1,9)
。@jnmonette当我使用#=不起作用时,我有更多的错误。。我还应该如何调用谓词kakuro?我试过“?-kakuro([A,B,C,E,F,G,J,K,L,N,O,P])”我的错误是:错误未知程序:卡库罗/1(DWIM无法纠正目标)。。。如果我问你呢?-卡库罗。还是?-卡库罗(左)。或者?-卡库罗([L])或者?-卡库罗。还是同样的错误谢谢你!我真的很感谢你的帮助!!祝你今天愉快:)非常感谢!我真的很感谢你的帮助!!祝您愉快:)