Prolog 使用CLPFD库的加密算法解谜器

Prolog 使用CLPFD库的加密算法解谜器,prolog,clpfd,cryptarithmetic-puzzle,Prolog,Clpfd,Cryptarithmetic Puzzle,我见过一些使用Prolog的clfpd库的Cyrpt算术解谜器的示例。例如,如果我有一个拼图AM+PM=DAY,它可以将0到9之间的不同值分配给不同的字母表,这样a*10+M+P*10+M=D*100+a*10+Y。我正在尝试编写一个通用版本。请注意,我对Prolog或clfpd都没有什么经验 我打算根据输入生成约束。例如,将基于输入谜题1生成*10+M+P*10+M=D*100+A*10+Y([A,M]+[P,M]=[D,A,Y])。但是我不知道怎么做。我编写了一个Prolog函数(称为con

我见过一些使用Prolog的clfpd库的Cyrpt算术解谜器的示例。例如,如果我有一个拼图AM+PM=DAY,它可以将0到9之间的不同值分配给不同的字母表,这样a*10+M+P*10+M=D*100+a*10+Y。我正在尝试编写一个通用版本。请注意,我对Prolog或clfpd都没有什么经验

我打算根据输入生成约束。例如,将基于输入谜题1生成*10+M+P*10+M=D*100+A*10+Y([A,M]+[P,M]=[D,A,Y])。但是我不知道怎么做。我编写了一个Prolog函数(称为convert),它基于输入创建一个约束。但它不起作用,我不断地出错

clpfd_expression' expected, found `convert([_818,_894])

有人能把我引向正确的方向吗。

您的代码中有两个错误。首先,convert/2是一个带有两个参数的谓词——不能将其用作函数。因此,与其

Exp01 #= convert(As)
简单地写

convert(As, Exp01)
另一个错误是

As #= [H1|_]
在这里,您希望从结构上将列表分解为,并提取其第一个元素。实现这一点的方法是简单的统一,即

As = [H1|_]
不同之处在于,
#=
实现(整数)算术相等(意味着它将两边都解释为算术表达式),而
=
是纯符号操作,这正是您在这里想要的

您可以在

工作代码中找到与您类似的程序:

:- use_module(library(clpfd)).
%calculate correct multiplier
%For example if AM, multipler of A is 10 and of M is 1 
multiple(1,10). 
multiple(N,F) :-  
    N>0, 
    N1 is N-1, 
    multiple(N1,F1), 
    F is 10 * F1.
%convert accepts input as a list. For instance [A,M]
%outputs a constraint of the form A*10 + M*1
convert([H|T], Ans):-
    length(T, Len),
    Len = 0,
    Ans = H * 1.
convert([H|T], Ans):-
    length([H|T], Len1),
    Len2 is Len1-1,
    multiple(Len2,Multiplier),
    convert(T, Ans1),
    Ans = Ans1 + H * Multiplier.


puzzle1(As + Bs = Cs) :- 
   append([As,Bs,Cs],Ds),
   term_variables(Ds,Var),   %% this will get all Var
   Var ins 0..9, 
   all_different(Var),
   convert(As, Ans1),
   convert(Bs, Ans2),
   convert(Cs, Ans3),
   %Generates a constraint depending on the input
   %For instance if input is puzzle1([A,M] + [P,M] = [D,A,Y])
   %Output constraint = A*10 + M + P*10 + M  = D*100 + A*10 + Y 
   Ans1 + Ans2 #= Ans3,
   As = [H1|_],
   Bs = [H2|_],
   H1 #\=0,
   H2 #\=0,
   label(Var),
   write("Solution: "),
   write(As + Bs = Cs).


%puzzle1([A,M]+[P,M]=[D,A,Y]).
%puzzle1([A,M]+[I]=[O,K]).
%puzzle1([Y,O,U]+[A,R,E]=[D,O,N,E]).
%puzzle1([S,E,N,D]+[M,O,R,E]=[M,O,N,E,Y]).
%puzzle1([R,O,A,D]+[I,N]=[U,S,A]).
%puzzle1([B,I,K,E]+[F,O,R]=[R,I,D,E]).

那么,你想要的行为是什么?你能举一些例子吗?看看我之前的答案,获得一些启发!2失去了什么?-)通过一些调试,我能够挑出那些错误。谢谢你的解释。
:- use_module(library(clpfd)).
%calculate correct multiplier
%For example if AM, multipler of A is 10 and of M is 1 
multiple(1,10). 
multiple(N,F) :-  
    N>0, 
    N1 is N-1, 
    multiple(N1,F1), 
    F is 10 * F1.
%convert accepts input as a list. For instance [A,M]
%outputs a constraint of the form A*10 + M*1
convert([H|T], Ans):-
    length(T, Len),
    Len = 0,
    Ans = H * 1.
convert([H|T], Ans):-
    length([H|T], Len1),
    Len2 is Len1-1,
    multiple(Len2,Multiplier),
    convert(T, Ans1),
    Ans = Ans1 + H * Multiplier.


puzzle1(As + Bs = Cs) :- 
   append([As,Bs,Cs],Ds),
   term_variables(Ds,Var),   %% this will get all Var
   Var ins 0..9, 
   all_different(Var),
   convert(As, Ans1),
   convert(Bs, Ans2),
   convert(Cs, Ans3),
   %Generates a constraint depending on the input
   %For instance if input is puzzle1([A,M] + [P,M] = [D,A,Y])
   %Output constraint = A*10 + M + P*10 + M  = D*100 + A*10 + Y 
   Ans1 + Ans2 #= Ans3,
   As = [H1|_],
   Bs = [H2|_],
   H1 #\=0,
   H2 #\=0,
   label(Var),
   write("Solution: "),
   write(As + Bs = Cs).


%puzzle1([A,M]+[P,M]=[D,A,Y]).
%puzzle1([A,M]+[I]=[O,K]).
%puzzle1([Y,O,U]+[A,R,E]=[D,O,N,E]).
%puzzle1([S,E,N,D]+[M,O,R,E]=[M,O,N,E,Y]).
%puzzle1([R,O,A,D]+[I,N]=[U,S,A]).
%puzzle1([B,I,K,E]+[F,O,R]=[R,I,D,E]).