2012-11-10 29 views

回答

4

什么:

loop(N) :- 
     between(1, N, X), 
     writeln(X), 
     false. 
+1

不使用重复。这是必需的。注意你的谓词循环/ 1失败,而其他成功。 – joel76

+1

或者当您想要谓词循环/ 1的成功时,您也可以替换...,false,...,false;真正。 –

+1

repeat/0在这种情况下是无意义的 - 如果你坚持显示,你可以在false/0后面加上。还要注意,例如'? - loop(-3)'与其他版本一起循环,而它与我的终止。 – mat

3

你可以使用断言/收缩例如

:- 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, 
    !. 
+0

Thans为您的答复。但在这一点上,我不认为我们被允许使用你给我看的这些谓词。 (动态,rectratcall,断言,收回)。我们允许使用的是'repeat/0'&'between/3',剪切'!'和基本的控制器,不再:/ –

+0

添加动态的东西就像一个循环一样简单,对我来说似乎是一个不好的习惯。 –

1

我终于使它工作使用谓词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. 
+1

一个非常好的解决方案,更好的是我的。 – joel76

+1

上面的重复是不需要的。你可以自己尝试,并删除重复,它将工作完全一样。你也应该告诉你的老师,重复和两者结合是没有意义的。 –

+1

重复只适用于没有生成器的无限循环。但是之间已经是发电机。你也不需要X = N,!,它已经为你做了。将其替换为失败。 –

2

你原来不因种种原因工作,但在特定的

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

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

+0

感谢您的回复。我注意到“是”不起作用,但未能扣除原因。所以,如果我不能这样做,是否有其他方法可以使用每次“重复”循环递减的变量? –

+0

“变量”是不是“变量”在序言所以你要么做递归,或者使用类似之间的捧出来的数字 – Anniepoo

2

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. 
+0

一连串的谢谢合租多少:^) –

+0

当心!您的第一个定义不会终止:'dec(1),false' – false

1

我会介绍一个服务谓词

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

这是需要在新的变量范围内(实际上解决了Anniepoo在她的第一个响应中强调的点)。

然后,我可以写

loop(N) :- 
    repeat, 
    isint(I), 
    write(I), nl, 
    I >= N, !. 
-1

我会专注于一个可选的解决方案,因为早些时候的评论已经凸显与原来的解决方案的问题。

loop(N):- 
    repeat, 
    (between(1,N,X), 
     write(X), nl, 
     fail, 
    ; !). 
+0

请注意,您不需要调用'repeat/0',因为对/ between之间的调用将通过回溯枚举'1 '和'N'。此外,你定义的'loop/1'会每次重新打印*你回溯到它。绝对不是你想要的。 –