如何检查Prolog列表中的每个元素是否大于0?

时间:2013-02-07 03:28:04

标签: list recursion prolog

我有以下Prolog谓词原型:solution(+ InputVector),其中InputVector是未知长度的值列表。如果列表中的所有值都大于0,则打印出一条消息。我该怎么做呢?

4 个答案:

答案 0 :(得分:3)

如果您有兴趣将学习扩展到“更高阶”谓词,请考虑maplist / 2:

3 ?- maplist(<(0), [1,2,3]).
true.

4 ?- maplist(<(0),[0,1,2,3]).
false.

答案 1 :(得分:2)

尝试检查列表是否为[]或[X | Xs],并采取相应的行动。

答案 2 :(得分:1)

你快到了。请考虑以下事项(感谢@aBathologist更新):

  1|  solution([X]) :- 
  2|     X > 0, 
  3|     !,
  4|     write_ln('Success!').
  5|  solution([X|Y]) :- 
  6|     X > 0,
  7|     solution(Y).

让我们逐行思考这实际上是如何运作的:

  1. 定义谓词solution/1的第一个子句,它将包含X单元素列表作为参数。
  2. 测试项目X是否为> 0的数字。如果没有,谓词将在此处终止并失败。否则,Prolog将继续下一行。
  3. 虽然不是绝对必要,但是cut(!)这里删除了Prolog在(1)处生成的选择点,假设第(6)行的第二个子句也可以用输入{执行} {1}},因为这相当于[X] [X|Y] = Y。因此,这只是为了提高效率所谓的'grue'切割。
  4. 由于列表[]包含大于零的元素,谓词会打印一条消息并继续。
  5. 定义谓词[X]的第二个子句,该子句采用包含一个或多个项的列表,其中solution/1是列表的头部,{{1} }是列表的尾部(余数)(它本身就是一个空的列表:X)。
  6. 与第(2)行相同。
  7. 继续递归测试列表的其余部分Y
  8. 请注意,上述定义假定[]必须仅在大于零的非空数字列表上成功。如果您希望允许此谓词在空列表上成功,则可以使实现更简单:

    Y

    在这个版本中,solution/1的两个子句中的任何一个基于参数执行:第一个处理空列表,第二个处理非空数字列表大于零。这里不需要剪切(solution([]) :- write_ln('Success!'). solution([X|Y]) :- X > 0, solution(Y). ),因为谓词参数是不可统一的(solution/1 \ = !)而Prolog不会为第一个子句的任何调用生成选择点

    我希望这有用,并且使Prolog语法的一些语义更清晰。

答案 3 :(得分:0)

我会像这样编写谓词:

all_greater_than_zero([]).
all_greater_than_zero([H|T]) :-
    H > 0,
    all_greater_than_zero(T).

我认为空列表是可以接受的。如果没有,您可以删除第一个条款。