2012-11-10 32 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'會每次重新打印*你回溯到它。絕對不是你想要的。 –