[英]Prolog Recursive Build List of [--I, ++J], while J>0
我正在嘗試將一個Prolog程序放在一起,該程序將接收一個數字和一個輸出列表,並從本質上列出[I,J]形式的列表,其中I + J =N。這是我的代碼,我得到的輸出:
loop(I, J, [[X,Y]|Lout]):-
I > 0,
I1 is I-1,
J1 is J+1,
X is I1,
Y is J1,
loop(I1, J1, Lout).
loop(I, J, [[I,J]]).
listFromLoop(N, W):-
loop(N,0,W).
輸出:
?- listFromLoop(4,W).
W = [[3, 1], [2, 2], [1, 3], [0, 4], [0, 4]] ;
W = [[3, 1], [2, 2], [1, 3], [1, 3]] ;
W = [[3, 1], [2, 2], [2, 2]] ;
W = [[3, 1], [3, 1]] ;
W = [[4, 0]].
我在末尾得到了兩個我不需要的額外元素([0,4],[0,4]),並且不得不逐步執行,而不是全部顯示為一個列表。
這是應該的樣子:
?- listFromLoop(4,W).
W = [[3, 1], [2, 2], [1, 3]].
我已經接近了,但是我認為我的主要問題是我試圖像對C ++或Java while循環那樣進行編碼。 但是,這似乎不是在Prolog中解決該問題的正確方法。
任何幫助將非常感激!
編輯
我想到了! 多一點閱讀后,似乎我缺少遞歸版本的基本情況。 這就是我最終解決的問題。 盡管我不確定這是否一定是Prolog中正確/最有效的方法。
loop(1,_,[]):- !.
loop(I, J, [[X,Y]|Lout]):-
I > 0,
I1 is I-1,
J1 is J+1,
X is I1,
Y is J1,
loop(I1, J1, Lout).
listFromLoop(N, W):-
loop(N,0,W).
您的代碼很好,但是我會做一些事情來清理它:
build(1, _, []).
build(I, J, [[X, Y]|Zs]) :-
I > 1,
X is I - 1,
Y is J + 1,
build(X, Y, Zs).
build(N, W) :- build(N, 0, W).
您並不是真正在使用循環-構建列表的是遞歸。 所以就稱它為build
。 定義具有相同名稱但參數數量不同的謂詞也很好。
我也將Lout
命名為Zs
因為這有助於表明它是一個列表-Prolog通常並不關心輸入或輸出。 您可以運行查詢?- build(6, [[5, 1], [4, 2], [3, 3], [2, 4], [1, 5]]).
即使將輸出列表作為輸入參數發送,您也將獲得成功。
更慣用的方式:
listFromLoop(U,W) :- U_ is U-1,
findall([I,J],(between(1,U_,J),I is U_-J+1),W).
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.