1

在练习中,我必须编写一个使用重复/0 打印数字 < N 的谓词,这是我尝试过的:

loop(N) :-
    repeat,
        write(N), nl,
        N is N-1,
        write(N),
        N > 0,
    !.

但它只会无休止地打印给定的数字 N。

任何想法如何使用repeat/0?谢谢你

4

7 回答 7

2

您的原始版本由于各种原因无法正常工作,但特别是

loop(N) :-
    repeat,
        write(N), nl,
        N is N-1,                <--- no!
        write(N),
        N > 0,
    !.

“is”统一了左边是否是右边的数学结果。左侧将绑定到右侧。一旦你在 Prolog 中设置了它,你就不能改变它的值。

于 2012-11-10T20:36:22.187 回答
2

我终于使用谓词使它工作了,between/3这是我的最终代码:

loop(N) :-
    repeat,
        between(1, N, X),
        writeln(X),
        X = N,
    !.

编辑:正如@CookieMonster 所说,repeat/0不需要,所以这是代码的最后一个版本:

loop(N) :-
        between(1, N, X),
        writeln(X),
        false.
于 2012-11-10T16:38:34.320 回答
2

您可以使用断言/撤回,例如

:- dynamic value/1.
loop(N) :-
    retractall(value(_)),
    assert(value(N)),
    repeat,
            retract(value(V)),
            writeln(V),
            V1 is V - 1,
            assert(value(V1)),
            V = 0,
    !.
于 2012-11-10T15:58:34.340 回答
2

关于什么:

loop(N) :-
        between(1, N, X),
        writeln(X),
        false.
于 2012-11-10T17:54:10.463 回答
1

我会介绍一个服务谓词

isint(I) :- I = 0 ; isint(T), I is T + 1.

这需要在一个变量的范围内进行(实际上解决了 Anniepoo 在她的第一个回复中强调的点)。

然后我可以写

loop(N) :-
  repeat,
  isint(I),
  write(I), nl,
  I >= N, !.
于 2012-11-11T06:32:25.603 回答
1

Abderrahmane 询问如何减少。

几种方法可以做到这一点。大多数人会做

dec(0).
dec(N) :-
   write(N), nl,
   NewN is N - 1,
   dec(NewN).

如果你坚持一个失败驱动的循环,怎么样

dec(N) :-
    between(1,N,X),
    Dec is 11 - X,
    write(Dec), nl,
    Dec = 1.

或者,这是丑陋和糟糕的风格(而且像糖蜜一样缓慢):

dec(N) :-
      assert(current_n(N)),
      repeat,
      current_n(Y),
      write(Y), nl,
      NewY is Y - 1,
      retractall(current_n(_)).
      assert(current_n(NewY)),
      Y > 0.
于 2012-11-11T04:00:57.827 回答
0

A simple way :

loop(N) :-
    between(1, N, X),
    writeln(X),
    X >= N, !.
    loop(X).
于 2018-05-21T16:41:13.837 回答