Prolog中sum的解决方案

时间:2019-04-02 21:23:22

标签: prolog

我绝对是新手。我刚刚阅读了基础教程,并试图自己解决一个快速问题。问题是,找到导致总数的可能数字组合。我期待这样的事情:

sum(A,B,11).

这应该得出A和B的值,它们的总和为10。

我的初始代码是这样:

sum(A,B,C):-
    C is A + B.

但是我没有得到任何结果。我得到以下信息。

ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR:    [9] 11 is _3302+_3304
ERROR:    [7] <user>
ERROR: 
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.

我对Prolog的了解缺少什么?

2 个答案:

答案 0 :(得分:5)

标准is/2谓词需要第二个参数的可算术表达式。因此,根据您的情况,您将需要为AB生成可能的值,以便可以计算A + B。为了使其实用,您将需要限制可能值的范围。例如:

?- between(1,7,A), between(1,7,B), sum(A,B,11).
A = 4,
B = 7 ;
A = 5,
B = 6 ;
A = 6,
B = 5 ;
A = 7,
B = 4 ;
false.

随着您对Prolog的学习不断发展,您最终可能对学习约束求解器感兴趣。

答案 1 :(得分:3)

  

这应该得出A和B的值,它们的总和为10。

如果您还考虑负数,则可能会有无限的结果:.. -100+111, -2+13, -1+12, 0+11, 1+10, 2+9, 150+-139 ..

您的程序将确认总和,并在给定A和B输入的情况下执行计算:

?- sum(2,9,11).
true

?- sum(2,9,C).
C = 11

但是即使您忽略其中之一,它也无法解决。

?- sum(A,9,11).
is/2: Arguments are not sufficiently instantiated

您希望Prolog会直指您的意思是“ 0到11之间的数字加起来等于11”,但是Prolog看到了一个潜在的无限搜索空间,无法开始搜索,也无法缩小搜索范围。

Paulo Moura的答案将生成范围内的数字,并将其全部测试,并显示哪些对满足A + B = C。他提到了约束求解器,这是流行的Prolog实现可用的库,它们具有解决此类问题的更通用的方法。以某种方式约束解决方案空间(“ A和B是正整数”),您要知道尽可能多的约束,然后他们将这些规则应用于数字推理,应用更多技术来寻找答案而无需搜索每个可想象的数字:< / p>

% load the 'clpfd' code
:- use_module(library(clpfd)).

% define a sum using the imported #= instead of "is"
mysum(A, B, C) :-
    C #= A + B.


% declare that A and B are positive,
% and solve for A and B values.
?- mysum(A, B, 11), A in 0..sup, B in 0..sup, label([A,B]).

在这种情况下,它最终是更多的代码,但是如果您通常希望Prolog为您解决数值计算,则您可能必须朝这个方向发展,而不是使用between()并进行所有数字列出自己。