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

发布于 2024-10-31 10:06:09 字数 986 浏览 4 评论 0 原文

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

z祗昰~ 2024-11-07 10:06:09

您的策略确实是合理的并且确实有效,至少使用内置的 scalar_product/4。我不熟悉 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 执行它。

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 of powlist/2. I recommend that you try the following instead:

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

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:

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).

This version (my_scalar_product/4) assumes the same interface as the built-in scalar_product/4, but it adds the constraint to the store instead of attempting to execute it using is/2.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文