Prolog - 将列表中的所有数字加 1

标签 prolog failure-slice

我试过了

 fun([],[]).
 fun([A|_],B) :- number(A), B is A +1,!.
 fun([H|T],R) :- fun(T,R).

我知道错了,你能帮我吗?谢谢

最佳答案

如果发现你的程序无法运行,你可以尝试一下:

?- fun([1],L).
   L = 2.
?- fun([1],[]).
   true.
?- fun([X],L).
   L = [].

因此,这清楚地显示了非关系行为:在第一个查询中,我们要求 L 并得到 L = 2 作为答案,但随后我们询问 [] 是答案;并且系统也接受这一点。显然,你的定义不能是一种关系。罪魁祸首肯定是削减。

除此之外,还有其他方式来查看问题。只看一条规则就足够了。第一个规则 (fun([A|_],B) :- number(A), B is A +1,!.) 表示第二个参数必须是整数(在某些情况下) )。但它应该是一个列表。第二条规则 (fun([H|T],R) :- fun(T,R).) 表示可以跳过任何元素。显然,这不能成为有意义的定义的一部分。

最简洁的方法是使用高阶谓词 maplist/3library(lambda) 中定义的 lambda 表达式。这样编写时,通常不使用中间谓词。

fun(Xs, Ys) :-
   maplist(\X^Y^(Y is X+1), Xs, Ys).

下一个版本将避免使用 lambda 并使用具体的定义:

msucc(X, Y) :-
   Y is X+1.

fun(Xs, Ys) :-
   maplist(msucc, Xs, Ys).

事实上,有一个预定义谓词 succ/2 出现在许多 Prolog 中,即 part of the Prolog prologue .

fun(Xs, Ys) :-
   maplist(msucc, Xs, Ys).

最“简单”的定义方式是直接使用谓词定义:

fun([], []).
fun([X|Xs], [Y|Ys]) :-
   Y is X+1,
   fun(Xs, Ys).

你更喜欢哪一个?

有关maplist系列的更多信息:Prolog map procedure that applies predicate to list elements


如果你想学习 Prolog,首先要坚持纯关系。避免割伤。避免诸如write之类的副作用。甚至避免 (is)/2。使用及以后 。学习终止与不终止 ,和 .

关于Prolog - 将列表中的所有数字加 1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24294944/

相关文章:

prolog - 内置 Prolog 谓词的性能 (is)/2

concurrency - 接收目标列表作为输入的元谓词

prolog - 在序言中将两个无序列表合并为有序列表

list - 序言列表在任何位置插入

Prolog 谓词 - 无限循环

序言——生成整数 "unwindably"

Prolog - 证明树错过了可能性

Prolog 合并排序的实现不会停止

prolog - 递归谓词中的回溯