Recursion 序言倒计时

Recursion 序言倒计时,recursion,prolog,countdown,clpfd,Recursion,Prolog,Countdown,Clpfd,你好,我试着写一个倒计时的递归 用prolog语言 我试着编写一些类似这样的代码: down(Y,X):- Y>0,K is Y-1,down(K,X). down(N, X) :- N0 is -N, between(N0, 0, X0), X is -X0. 但它的返回是“错误的” 我不知道为什么它返回布尔结果。。。 它需要在X中插入K值。。。 一般来说,如何使递归始终返回某个数字 我需要做什么 tnx很多false不是规则返回的布尔结果。这是Prolog解释器本

你好,我试着写一个倒计时的递归

用prolog语言

我试着编写一些类似这样的代码:

down(Y,X):- Y>0,K is Y-1,down(K,X).
down(N, X) :- N0 is -N, between(N0, 0, X0), X is -X0. 但它的返回是“错误的” 我不知道为什么它返回布尔结果。。。 它需要在X中插入K值。。。 一般来说,如何使递归始终返回某个数字

我需要做什么


tnx很多

false
不是规则返回的布尔结果。这是Prolog解释器本身返回的结果,表明它无法找到查询的答案

您的
down
规则说明当
Y
高于零时该怎么办,但它没有说明当
Y
达到零或低于零时该怎么办。在“Prolog speak”中,您的规则被认为缺少基本子句

添加base子句后,您的规则将成功:

down(Y,_) :- Y < 0.

down(Y,X):-
    Y>=0,
    write(X), write(' = '), write(Y), nl,
    K is Y-1,
    down(K,X).
down(Y,u):-Y<0。
向下(Y,X):-
Y> =0,
写入(X)、写入('=')、写入(Y)、nl、,
K是Y-1,
向下(K,X)。

您现在需要做的就是确保递归规则打印出一些内容()。

在谓词中加入副作用(如打印)通常是不好的做法。但另一方面,您的问题并没有明确说明如何获得递减值

无论哪种方式,计数器的逻辑如下:

down(N, N). % the counter value
down(N, X) :-
    succ(N0, N), % one less, until you reach zero
    down(N0, X). % next counter value
然后,您可以简单地查询:

?- down(3, X).
或者,如果愿意,您可以一次打印所有内容:

?- forall( down(3, X), format("X = ~d~n", [X]) ).
有关使用SWI Prolog的SWISH的演示,请参阅


一些注释:使用
succ/2
可以确保第一个参数是非负整数。使用
forall/2
打印演示了如何明确副作用。

作为@Boris答案的替代方法,您也可以使用以下方法:

down(Y,X):- Y>0,K is Y-1,down(K,X).
down(N, X) :- N0 is -N, between(N0, 0, X0), X is -X0. 错过答案?给你

?- use_module(library(clpfd)). true. ?- X in 0..5, labeling([down], [X]). X = 5 ; X = 4 ; X = 3 ; X = 2 ; X = 1 ; X = 0. ?- (). 对。 ?-X0..5,([向下],[X])。 X=5 ; X=4 ; X=3 ; X=2 ; X=1 ; X=0。
@卡利梅罗不用谢。按照使用
succ/2时堆栈溢出.s(X)的惯例,进行投票并接受!我可能错了,但几乎可以肯定你的程序中有一个bug。你检查
Y>0
,你总是减去1,然后你检查
Y<0
Y
在某一点上应该正好为0?@Boris你是对的,因为OP希望输出中为0,所以我需要修改第二个子句以使用
=
而不是
。谢谢