0

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

例如,函数调用: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,序列将继续附加到结果列表中。

提前致谢!我已经为此奋斗了很久!

4

2 回答 2

1

逐行:

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

    糟糕的风格:这个名字暗示了另一个功能

  2. First <= Last,

    “小于或等于”运算符是 =<

  3. append(First,Result,Result),

    您正在传递 INT、LIST、LIST,但 append/3 具有签名 LIST、LIST、LIST,并且您想要更新值,但 Prolog 中的变量是“不可变的”,只有在 Result 不变的情况下,这样的调用才能成功

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

    算术表达式必须显式计算,这里你传递一个结构 +(First,1)

当测试(一旦更正)失败时,您也会错过编写所需行为的代码。怎么样First>Last

于 2012-11-30T07:41:07.153 回答
0

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

其次,写作append(First, Result, Result)意味着“通过附加FirstResult你再次获得”,除非是空列表,否则Result它总是会失败(阅读:生产) ,因为如果你将某些东西附加到一个列表中,你会获得一个比你开始时更长的列表。您显然无法区分and中的两个s - 它们确实不一样。另请注意,这适用于列表,因此,并且必须都是可以实例化为列表的列表或术语,否则它将失败。这正是您的情况,因为它始终是一个数字 - 绝对不是列表,而是它的成员。所以你不应该使用:使用列表构造和统一falseFirstResultappendcountappend(A, B, C)ABCFirstappend=将元素附加到列表并将获得的结果绑定到变量,例如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 完全实例化为数字时才有效(它不能反转)。

于 2012-11-30T14:55:27.420 回答