我想知道是否有任何方法可以在 Prolog 中通過空輸入實作迭代。例如,我希望第一次迭代為 0,下一次迭代為 1,第二次迭代為 2,依此類推。
uj5u.com熱心網友回復:
從您的評論中:
示例:
iterate()是我的查詢,每次我呼叫它時,我希望輸出為 0 第一次 1 第二次,依此類推。
應該不會比這更困難:
increment(N) :- inc(0,1,N).
inc(C , _ , C ) .
inc(C , S , N ) :- C1 is C S, inc(C1,S,N).
分解它,Prolog 編程中一個非常常見的習慣用法是使用輔助謂詞。由于 prolog 沒有任何型別的迭代結構,它只有遞回和回溯,通常為了做一些有用的事情,你需要攜帶額外的狀態:比如計數器的當前值等。
所以 。. .
我們有我們的increment/1謂詞。它所做的只是呼叫一個輔助謂詞inc/3. 除了來自呼叫謂詞 ( ) 的變數之外,它還攜帶N兩個額外的狀態:
- 計數器的當前值(
C),以及 - 步長值(
S),在每次遞回呼叫中計數器應遞增的值。
這些狀態位分別用0和初始化1。
inc/3,我們的輔助謂詞只有兩個子句:
inc(C , _ , C ) .
inc(C , S , N ) :- C1 is C S, inc(C1,S,N).
它的作用是這樣的:
在初始進入謂詞時,進入謂詞的第一個子句,并且計數器的當前值與
N期望值一致,并且成功。在回溯時,該統一被撤消,并且進入謂詞的第二個子句。執行以下操作:
- 下一個值 (
C1) 被計算為當前值和步長值的總和。 inc/3遞回呼叫,傳遞C1,S和N.
- 下一個值 (
您可能會注意到這個謂詞是非終止的:如果您要運行inc(0,1,N), writeln(N), fail,您的 CPU 在開始寫入控制臺時會旋轉到 100%
0
1
2
3
4
. . .
uj5u.com熱心網友回復:
類似的問題
與succ/2:
nat(N) :-
nat(0, N).
nat(N, N).
nat(N0, N) :-
succ(N0, N1),
nat(N1, N).
或與call_nth/2:
nat(0).
nat(N) :-
call_nth(repeat, N).
現在,所有自然數:
?- nat(N).
uj5u.com熱心網友回復:
示例: iterate() 是我的查詢,每次我呼叫它時,我希望輸出為 0 第一次 1 第二次,依此類推。
如果您將狀態存盤在 Prolog 資料庫中并且不介意輸出有副作用并且可以處理在呼叫時不使用 () ,那么:
:- dynamic(iterate_counter/1).
iterate_counter(0).
iterate() :-
iterate_counter(X),
writeln(X),
succ(X, Y),
retract(iterate_counter(X)),
assert(iterate_counter(Y)).
?- iterate, iterate, iterate.
0
1
2
uj5u.com熱心網友回復:
incrementing(Lower, Increment, N) :-
integer(Lower),
integer(Increment),
% Fast integer comparison
Increment @>= 1,
incrementing_(Lower, Increment, N).
incrementing_(Lower, Increment, N) :-
nonvar(N), !,
integer(N),
% Can calculate, faster than iterating
N @>= Lower,
Diff is N - Lower,
divmod(Diff, Increment, _, 0).
incrementing_(Lower, Increment, N) :-
incrementing_loop_(Lower, Increment, N).
incrementing_loop_(Lower, _Increment, Lower).
incrementing_loop_(Lower, Increment, N) :-
Lower1 is Lower Increment,
incrementing_loop_(Lower1, Increment, N).
結果 swi-prolog:
?- incrementing(5, 3, N).
N = 5 ;
N = 8 ;
N = 11 ;
N = 14 ...
?- incrementing(5, 3, 11).
true.
?- incrementing(5, 3, 12).
false.
為了方便起見,可以包裝一下,例如:
iterate(N) :-
incrementing(0, 1, N).
結果:
?- iterate(-1).
false.
?- iterate(2).
true.
?- iterate(N).
N = 0 ;
N = 1 ;
N = 2 ;
N = 3 ...
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/507852.html
