繁体   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