我正在处理序言作业,目前非常接近解决方案。所以,问题是一个约束满足问题,我必须找到一组变量的值,以使某些条件成立。具体来说,给定 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
我不确定如何定义点积,以便它可以作用于变量(而不仅仅是原子)。其余所有代码都可以完美运行(我不想将其放在这里,因为这是入门序言课程中非常常见的问题,而且我不想给懒惰的人提供答案)。你们有什么建议?
I'm working on a prolog assignment and I'm currently very very close to the solution. So, the problem is a constraint satisfaction problem where I have to find values for a set of variables such that certain conditions are true. Specifically, given 3 words (W1,W2,W3), assign their variables such that W1+W2=W3. An example of this would be SEND+MORE=MONEY, or IT+IS=ME.
The constraints are: (1) they have to add up correctly, (2) the starting letter cannot be 0 (3) and all variables must be distinct. And it has to work for a general word problem. My issue is happening when I try to ensure that they add up correctly (I've met the other conditions and I understand the problem). In terms of the second word problem we should have:
10*I + 1*T
+10*I + 1*S
___________
10*M + 1*E
So, I have made a function that makes lists of powers of 10 in a certain length, like so:
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 also have the actual list of letters, say, [I,T,I,S,M,E]. I then constructed a list of coefficients (I'll explain that part later) out of powlist so we have something like the following: [10,1,10,1,-10,-1]. I did this so if we took the dot product between this list of coefficients and the list of letters, and it was zero, the constraint would be satisfied. But, I can't get this dot product theory to work. I currently have a line that says:
scalar_product(Coefficients, Letters, #=, 0)
But this is giving me the following error:
! Instantiation error in argument 2 of is/2
! goal: _102 is 0+10.0*_109
I'm not sure how to define dot product so it can work on variables (instead of just atoms). All of the rest of the code works perfectly (and I don't want to put it on here because this is a very common question for introductory prolog courses, and I don't want to give lazy people answers). What do you guys suggest?
发布评论
评论(1)
您的策略确实是合理的并且确实有效,至少使用内置的
scalar_product/4
。我不熟悉 SICStus 中这个谓词的定义,但它的界面似乎与 SWI-Prolog 中的相同。我可以提出一些建议。首先,也许您编写的代码的某些方面正在生成选择点,这些选择点在回溯中执行时(例如,寻求替代解决方案,例如通过
label/1
),解释器执行子目标_102 is 0+10.0*_109
其中_109
无意中未绑定。你写过包含这样一行的谓词吗?即使没有,我建议仔细检查您的代码,以确保它们不会生成不必要的选择点,例如您对powlist/2
的定义。我建议您尝试以下操作:此版本没有为 Prolog 解释器留下任何选择点可以回溯,这可能可以解决问题(不过,在没有看到更多代码的情况下,我根本无法判断)。
否则,如果您是正确的并且错误确实是从 scalar_product/4 的定义中产生的(尽管我会感到惊讶),那么也许您可以生成标量积约束项并将其添加到自己手动操作商店。例如,请考虑:
此版本 (
my_scalar_product/4
) 假定与内置scalar_product/4
具有相同的接口,但它将约束添加到存储中,而不是尝试使用is/2
执行它。Your strategy is indeed sound and does work, at least with SWI-Prolog CLP(FD) using the built-in
scalar_product/4
. I am unfamiliar with the definition of this predicate in SICStus, but it's interface appears to be the same as in SWI-Prolog.I can make a couple of suggestions. Firstly, perhaps some aspect of the code you've written is generating choicepoints which, when executed in backtracking (e.g., to seek alternate solutions, such as via
label/1
), the interpreter executes the subgoal_102 is 0+10.0*_109
where_109
is unintentionally unbound. Have you written a predicate which contains such a line? Even if not, I recommend double checking your code to ensure that they do not generate unnecessary choicepoints, such as your definition ofpowlist/2
. I recommend that you try the following instead:This version leaves no choicepoints for the Prolog interpreter to backtrack to, which might resolve the problem (though, without seeing more code, I simply can't tell).
Otherwise, if you are correct and the error is indeed emanating from within the definition of
scalar_product/4
(though I'd be surprised), then perhaps you could generate the scalar product constraint term and add it to the store yourself, manually. For example, consider:This version (
my_scalar_product/4
) assumes the same interface as the built-inscalar_product/4
, but it adds the constraint to the store instead of attempting to execute it usingis/2
.