Prolog - 如何保存递归调用的结果?

时间:2017-12-06 20:59:21

标签: recursion prolog

我仍在尝试理解Prolog逻辑,并偶然发现了一个问题。 我试图保存在递归调用中找到的值,传递或聚集。

因此:

main([]) :- !.
main([H|Tail]) :- findall(X,something(_,_,X),R),
                  getValueReturn(R,H,Lin, Lout),
                  main(Tail).


% X is the Head from main
getValueReturn([H|Tail],X,Lin, Lout) :- subset(X, H) ->
                                findall(A,something(A,_,H),L1),
                                append(Lin,L1,Lout), 
                                getValueReturn(Tail,X,Lout,L)
                                ;
                                getValueReturn(Tail,X,Lin,Lout).  

我想从getValueReturn中的findall收集结果,将它们组合起来,然后将它们发送回main,然后可以使用它们。 如何在getValueReturn中创建和添加列表? 同样,如何将列表保存在main中以进行所有递归调用?

修改

我根据评论回复编辑了上面的代码,但是当我通过跟踪运行时,列表会在找到空列表时删除所有元素。

我做错了什么?这是我第一次尝试使用通过递归构建列表的概念。

2 个答案:

答案 0 :(得分:0)

您应该使用示例数据发布可以运行的完整代码。我没有测试过这个。

您还需要在顶层传递L。对相邻过程中的不同参数使用相同的变量名称不会提高可读性。

main([E|Es],L0,L) :-
  findall(X,something(_,_,X),Rs),
  getValueReturn(Rs,E,L0,L1),
  main(Es,L1,L).
main([],L,L).

getValueReturn([R|Rs],E,L0,L) :-
  ( subset(E,R) ->
    findall(A,something(A,_,R),New),
    append(L0,New,L1), 
    getValueReturn(Rs,E,L1,L)
  ; getValueReturn(Rs,E,L0,L) ).
getValueReturn([],_,L,L).

变量在Prolog中只能有一个值。例如,在您的代码中,Loutappend/3的输出,是getValueReturn/4的递归调用的输入,然后是顶级的输出。这可能不会做你想要的。

答案 1 :(得分:0)

我发现做我正在尝试的最好方法是在找到结果时使用asserta / z,然后稍后收集这些结果。

否则代码变得过于复杂,无法按预期运行。