Prolog递归构建列表[ - I,++ J],而J> 0

时间:2018-03-05 23:43:02

标签: list recursion prolog

我试图整理一个Prolog程序,它将接收一个数字和一个输出列表,并基本上列出[I,J]形式的列表,其中I + J = N.这里&#39 ;我的代码,输出我得到:

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).

2 个答案:

答案 0 :(得分:0)

你的代码很好,但是我会做一些清理它的事情:

while True:
    line = input('Enter the GNSS message')
    print(line)
    if line == 'done':
        break   
    GNSS_data = line.split(" ")
    print("Timezone: {}".format(GNSS_data[-1]))
    print("Time: {}".format(GNSS_data[-2]))
    print("Date = {}".format(GNSS_data[-3]))
    print("\n")

你并没有真正使用循环 - 它是构建列表的递归。所以只需称它为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,因为这有助于表明它是一个列表 - prolog通常不关心输入或输出。您可以运行查询Zs,即使您已将输出列表作为输入参数发送,也会获得成功。

答案 1 :(得分:0)

更惯用的方式:

listFromLoop(U,W) :- U_ is U-1,
    findall([I,J],(between(1,U_,J),I is U_-J+1),W).