1

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

4

4 回答 4

4

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

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

4 ?- maplist(<(0),[0,1,2,3]).
false.
于 2013-02-08T16:13:42.760 回答
2

尝试检查列表是 [] 还是 [X|Xs],并采取相应措施。

于 2013-02-07T03:29:18.487 回答
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. 测试 itemX是否为> 0. 如果不是,谓词将在此处终止并失败。否则,Prolog 将继续下一行。
  3. 虽然不是绝对必要的,但!这里的 cut ( ) 删除了 Prolog 在 (1) 处生成的选择点,因为第 (6) 行的第二个子句也可以使用 input 执行[X],因为这相当于[X|Y]where Y= []。因此,这只是为了提高效率而进行的所谓的“格鲁特”削减。
  4. 由于列表[X]包含所有大于零的元素,谓词打印一条消息并成功。
  5. 定义谓词的第二个子句,solution/1它接受一个包含一个或多个项目X的列表,其中是列表的头部,并且Y是列表的尾部(剩余部分)(它本身就是一个可以为空的列表:)[]
  6. 与第 (2) 行相同。
  7. 继续递归测试列表的其余部分,Y.

请注意,上面的定义假定solution/1必须仅在大于零的数字的非空列表上成功。如果您希望允许此谓词在空列表上成功,则可以使实现更加简单:

solution([]) :- 
    write_ln('Success!').
solution([X|Y]) :-
    X > 0, 
    solution(Y).

在这个版本中,根据参数执行两个子句solution/1的一个:第一个处理空列表,第二个处理大于零的数字的非空列表。此处不需要cut ( !),因为谓词参数是不可统一的 ( []\= [X|Y]),并且 Prolog 不会为第一个子句的任何调用生成选择点。

我希望这对您有所帮助,并使 Prolog 语法的一些语义对您来说更加清晰。

于 2013-02-08T04:35:42.267 回答
0

我会这样写谓词:

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

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

于 2013-02-08T15:41:50.160 回答