【问题标题】:Solutions for sum in PrologProlog中求和的解决方案
【发布时间】:2019-04-02 21:23:21
【问题描述】:

我绝对是 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 的理解缺少什么?

【问题讨论】:

    标签: prolog


    【解决方案1】:

    标准的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 的学习取得进展,您最终可能会对学习约束求解器感兴趣。

    【讨论】:

      【解决方案2】:

      这应该会导致 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 是正整数”),尽可能多的约束,然后他们应用这些规则来推理数字,应用更多技术来找到答案,而无需搜索每个可以想象的数字:

      % 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() 并制作所有数字列表自己。

      【讨论】:

      • 谢谢。你能告诉我为什么 Prolog 在处理像我这样的查询时不会陷入无限循环吗?据我了解,没有针对停止问题的通用算法,即程序(prolog 编译器)如何知道搜索空间是无限大的,而我添加的任何约束使其不是无限的?
      • @NikhilVandanapu 抱歉,我太初学者了,无法回答这个问题。它不能解决停止问题,在某些情况下 Prolog 将永远循环。 Alex Moura 生成每个数字并创建一个小的搜索空间,并测试每个数字。约束库必须在幕后做类似的事情——它们必须从某个地方开始搜索。但是它们允许您在更高级别上工作,并将搜索空间与您所知道的事物联系起来——“答案不会在这里”。 CLP/FD 也比基本的 Prolog 了解更多的算术规则。但我不明白如何 - 这可能是魔法 ;-)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多