1

我正在尝试编写一个程序来解决一般的密码难题,例如 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)

我无法弄清楚这个错误是什么。有人可以帮我吗?

4

1 回答 1

2

您报告的错误可能是一个错字:[H1,T1],出现在几个地方。由于这个错字H2无意中被实例化为一个列表,导致 summation 语句出现问题。以下重现了 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它的数量。
  • 中的几个括号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).

这还没有解决这个难题......但是,由于它解决了您提到的错误 - 以及其他一些问题 - 您应该能够从这里开始。

于 2014-10-23T08:04:55.817 回答