带变量的Prolog点积(约束满足)

时间:2011-04-11 22:49:13

标签: prolog cryptarithmetic-puzzle

我正在进行一项prolog任务,目前我非常接近解决方案。因此,问题是约束满足问题,我必须找到一组变量的值,以便某些条件成立。具体地,给定3个字(W1,W2,W3),分配它们的变量,使得W1 + W2 = W3。一个例子是SEND + MORE = MONEY,或IT + IS = ME。

约束条件是:(1)它们必须正确加,(2)起始字母不能为0(3),所有变量必须是不同的。它必须适用于一般的单词问题。当我试图确保它们正确加起来时(我已经遇到了其他条件并且我理解了问题),我的问题正在发生。就第二个字问题而言,我们应该:

 10*I + 1*T
+10*I + 1*S
___________
 10*M + 1*E

所以,我已经制作了一个函数,使得一定长度的10的幂列表,如下所示:

powlist(1,L) :-
    append([1.0],[],L). 
powlist(N,L) :-
    N1 is N-1,
    X is 10**N1,
    powlist(N1,L1),
    append([X],L1,L),
    !.

我也有实际的字母列表,比如说,[I,T,I,S,M,E]。然后,我从powlist中构建了一个系数列表(我将在后面解释该部分),因此我们得到如下内容:[10,1,10,1,-10,-1]。我这样做,所以如果我们在这个系数列表和字母列表之间取点积,并且它是零,那么约束就会得到满足。但是,我不能让这个点积理论发挥作用。我目前有一行说:

   scalar_product(Coefficients, Letters, #=, 0)

但是这给了我以下错误:

!参数2中的实例化错误是/ 2
!目标:_102是0 + 10.0 * _109

我不确定如何定义点积,因此它可以处理变量(而不仅仅是原子)。所有其余的代码都完美无缺(我不想把它放在这里,因为这是一个非常常见的问题,对于入门prolog课程,我不想给懒惰的人答案)。你们有什么建议?

1 个答案:

答案 0 :(得分:1)

您的策略确实合理并且确实有效,至少使用内置scalar_product/4的SWI-Prolog CLP(FD)。我不熟悉SICStus中这个谓词的定义,但它的界面看起来与SWI-Prolog中的相同。

我可以提出一些建议。首先,也许您编写的代码的某些方面是生成选择点,当在回溯中执行时(例如,寻找替代解决方案,例如通过label/1),解释器执行子目标_102 is 0+10.0*_109 _109无意中未绑定。你写过一个包含这样一行的谓词吗?即使没有,我建议仔细检查您的代码,以确保它们不会生成不必要的选择点,例如powlist/2的定义。我建议您尝试以下方法:

powlist(1, [1]) :- !.
powlist(N, [F|Fs]) :-
    N > 1,
    N1 is N - 1,
    F is 10 ** N1,
    powlist(N1, Fs).

此版本没有为Prolog解释器留下任何选择点来回溯,可能解决问题(但是,如果没有看到更多代码,我根本无法分辨)。

否则,如果你是正确的并且错误确实来自scalar_product/4的定义(虽然我会感到惊讶),那么也许你可以生成标量产品约束术语并将其添加到商店亲自动手例如,考虑:

my_scalar_product([V|Vs], [C|Cs], Op, Value) :-
    construct_constraint(Vs, Cs, (V * C), Constr),
    Constraint =.. [Op, Constr, Value],
    Constraint.

construct_constraint([], [], Acc, Acc).
construct_constraint([V|Vs], [F|Fs], Acc, Res) :-
    construct_constraint(Vs, Fs, '+'(Acc, (V * F)), Res).

此版本(my_scalar_product/4)假定与内置scalar_product/4具有相同的接口,但它将约束添加到商店,而不是尝试使用is/2执行它。