通用prolog密码算法程序



我正试图编写一个程序来解决一般的密码算术难题,如AM+PM=DAY、SEND+MORE=MONEY。。

我写的程序是:

gsolve([H1,T1],[H2|T2],[H3|T3]):-
    gsolvehelper([H1,T1],[H2|T2],[H3|T3],[0,1,2,3,4,5,6,7,8,9],0).
gsolvehelper([H1,T1],[H2|T2],[H3|T3],D,C):-
    (   var(H1)->select(H1,D,D1);D1=D),
    (   var(H2)->select(H2,D1,D2);D2=D1),
    (   X1 is H1+H2+C),
    (   H3 is mod(X1,10)),
    (   C1 is X1//10),
    gsolvehelper(T1,T2,T3,D2,C1).

输入的形式为:

gsolve([A,M],[P,M],[D,A,Y]).

前两个列表的头被添加到进位中,以查找第三个列表和新进位的头,依此类推

我得到的错误是:

ERROR: is/2: Type error: `[]' expected, found `[2,_G3922]' ("x" must hold one character)

我搞不清楚这个错误是什么。有人能帮我吗?

您报告的错误可能是由于拼写错误:[H1,T1],出现在多个位置。由于这个拼写错误,H2在无意中被实例化到一个列表中,从而导致summary语句出现问题。以下再现了SWI7中的错误:

?- X is 1 + [1,_] + 3.
ERROR: is/2: Type error: `[]' expected, found `[1,_G11068]' (a list) ("x" must hold one character)

还有其他方法可以改进代码:

  • 由于您只需传递gsolve/3的参数,因此不需要在此处使用头/尾符号[H|T]
  • 您可以简单地将第二个谓词命名为gsolve/5,因为它与gsolve/3的arity已经不同了
  • bsolve/5中的几个括号是多余的。if/then运算符周围的间距也可以改进
  • 使用mod/2///2的组合可能会引入问题,因为///2的舍入(即,朝向零,通常至少…)与mod/2不一致。请改用div/2(向负无穷大取整)

根据以上内容进行更改我得到:

gsolve(L1, L2, L3):-
  gsolve(L1, L2, L3, [0,1,2,3,4,5,6,7,8,9], 0).
gsolve([H1|T1], [H2|T2], [H3|T3], D, C):-
  (   var(H1)
  ->  select(H1, D, D1)
  ;   D1 = D
  ),
  (   var(H2)
  ->  select(H2, D1, D2)
  ;   D2=D1
  ),
  X1 is H1 + H2 + C,
  H3 is mod(X1, 10),
  C1 is div(X1, 10),
  gsolve(T1, T2, T3, D2, C1).

这还不能解决难题。。。然而,由于它解决了您提到的错误,以及其他一些问题,您应该能够从这里接受它。

最新更新