簡體   English   中英

[--I,++ J]的Prolog遞歸構建列表,而J> 0

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM