我已经看到了一些使用Prolog的clfpd库进行密码算术难题求解器的示例。例如,如果我有一个谜题AM + PM = DAY,它可以将0到9的不同值集分配给不同的字母,以便A * 10 + M + P * 10 + M = D * 100 + A * 10 + Y 。我正在尝试编写它的通用版本。请注意,我对Prolog或clfpd的经验很少。
我打算根据输入生成约束。例如,将基于输入拼图1([A,M] + [P,M] = [D,A,Y]生成A * 10 + M + P * 10 + M = D * 100 + A * 10 + Y ])。但是我不知道该怎么做。我已经编写了Prolog函数(称为convert),该函数根据输入创建约束。但是它不起作用,我不断收到错误
clpfd_expression' expected, found `convert([_818,_894])
:- 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 #= N-1,
multiple(N1,F1),
F #= 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 #= Len1-1,
multiple(Len2,Multiplier),
convert(T, Ans1),
Ans #= Ans1 + H * Multiplier.
%add should imply constraint A*10+M+P*10+M=D*100+A*10+Y.
add(Exp1, Exp2, Exp3):-
Exp1 + Exp2 #= Exp3.
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),
Exp01 #= convert(As),
Exp02 #= convert(Bs),
Exp03 #= convert(Cs),
add(Exp01, Exp02, Exp03),
%add constraint first member of each list cant be asigned a value 0
As #= [H1|_],
Bs #= [H2|_],
Cs #= [H3|_],
H1 #\=0,
H2 #\=0,
H3 #\=0.
有人可以指引我正确的方向。
答案 0 :(得分:2)
您的代码中有两个错误。首先,convert / 2是带有两个参数的谓词-您不能将其用作函数。所以,而不是
Exp01 #= convert(As)
简单地写
convert(As, Exp01)
另一个错误是
As #= [H1|_]
在这里您想在结构上分解列表As
并提取其第一个元素。做到这一点的方法是简单的统一,即
As = [H1|_]
不同之处在于#=
实现(整数)算术相等(意味着将双方都解释为算术表达式),而=
是纯符号操作,这就是您想要的。
您可以在http://eclipseclp.org/examples/cryptarith.ecl.txt上找到与您的程序类似的程序