简单的递归Prolog函数

时间:2012-11-30 00:51:08

标签: recursion prolog

我正在尝试创建一个简单的函数,在给定第一个和最后一个数字的列表中打印整数。

例如,函数调用:count(3,7,Z)将打印“Z = [3,4,5,6,7]”

到目前为止,这是我的尝试:

count(First,Last,Result):-
  First <= Last,
  append(First,Result,Result),
  count(First+1,Last,Result).

我究竟做错了什么?我们的想法是,只要First小于或等于last,序列将继续附加到结果列表中。

提前致谢!我一直在争取这个很长一段时间!

2 个答案:

答案 0 :(得分:1)

逐行:

  1. count(First,Last,Result):-

    糟糕的风格:名称提示另一种功能

  2. First <= Last,

    'less or equal'运算符=&lt;

  3. append(First,Result,Result),

    你正在传递INT,LIST,LIST,但追加/ 3有签名列表,列表,列表和 你想要一个值更新,但Prolog中的变量是'不可变的',这样的调用只有在Result不变的情况下才能成功

  4. count(First+1,Last,Result).

    算术表达式必须显式评估,此处传递结构+(First,1)

  5. 您还错过了对测试(一旦更正)失败所需的行为进行编码。那么First>Last呢?

答案 1 :(得分:0)

您的计划存在许多问题。首先,当你写3 + 2 Prolog时,不像任何其他语言那样计算结果。您必须明确要求进行计算并通过谓词is将计算结果绑定到变量,例如X is 3 + 2, ...,然后您将X绑定到5在规则尾部的其余部分使用。

其次,写append(First, Result, Result)表示“将First追加到Result,再次获得Result”,这将永远失败(阅读:生成false)除非First是空列表,因为如果您将某些内容附加到列表中,则会获得比您开始时更长的列表。你明显无法区分Resultappend中的两个count - 它们实际上并不相同。另请注意,append(A, B, C)适用于列表,因此ABC必须都是可以实例化到列表的列表或术语,否则它将失败。这正是你的情况,因为First始终是一个数字 - 绝对不是一个列表,而是一个成员。因此,您不得使用append:使用列表构造和与=的统一将元素附加到列表并将获得的结果绑定到变量,例如X = [Element | List]

最后,如果以上都是正确的,那么您的谓词将会失败,因为您没有定义归纳的基本情况。换句话说:当你的谓词回答[]时?当CapelliC评论First > Last时,必须发生这种情况:在这种情况下,范围为空,Result也必须为空。在您的程序中,当发生这种情况时,谓词明显失败(请注意,当您编写foo(X, Y) :- X >= 0, Y is X + 1.时,这意味着每当X小于零时失败)。作为递归的基本情况的空范围,对谓词的评估迟早会在那里结束,因此它总是会失败。

最后,你应该写一些类似的东西:

ints(First, Last, Interval) :- First > Last -> Interval = [] ;
  NFirst is First + 1, ints(NFirst, Last, NInterval), Interval = [First | NInterval].

(我为你的谓词和变量提供了更多的声明性名称)。当然,只有当First和Last被完全实例化为数字(它不能被反转)时,这个谓词才会起作用。