【问题标题】:Prolog dot product with variables (constraint satisfaction)带变量的 Prolog 点积(约束满足)
【发布时间】:2011-04-11 22:49:12
【问题描述】:

我正在处理序言任务,目前我非常接近解决方案。所以,问题是一个约束满足问题,我必须找到一组变量的值,使得某些条件为真。具体来说,给定 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)

但这给了我以下错误:

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

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

【问题讨论】:

    标签: prolog cryptarithmetic-puzzle


    【解决方案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 执行它。

    【讨论】:

      猜你喜欢
      • 2020-10-29
      • 1970-01-01
      • 2022-11-10
      • 1970-01-01
      • 1970-01-01
      • 2015-08-24
      • 1970-01-01
      • 2012-12-28
      • 2020-09-14
      相关资源
      最近更新 更多