PROLOG中的递归?

PROLOG中的递归?,prolog,Prolog,鉴于以下序言事实: f(a, [b]). f(b, [c]). f(c, [d]). f(d, [e]). f(e, []). 我需要创建一个查询xyz(a,Y),以便得到Y=[e,d,c,b],因为a依赖于b,b依赖于c,等等。 我目前的查询是: xyz(X,Y):- f(X,P), member(Y,[P]). 但是,对xyz(a,Y)的查询只给出Y=[b],而不是b的依赖项等 我想也许我可以将这两行添加到上面查询的末尾,但这并不像我希望的那样有效。由于上一个自由查询成功地检索了

鉴于以下序言事实:

f(a, [b]).
f(b, [c]).
f(c, [d]).
f(d, [e]).
f(e, []).
我需要创建一个查询
xyz(a,Y)
,以便得到
Y=[e,d,c,b]
,因为a依赖于b,b依赖于c,等等。 我目前的查询是:

xyz(X,Y):-
  f(X,P),
  member(Y,[P]).
但是,对
xyz(a,Y)
的查询只给出
Y=[b]
,而不是b的依赖项等

我想也许我可以将这两行添加到上面查询的末尾,但这并不像我希望的那样有效。由于上一个自由查询成功地检索了a的依赖项b,我希望接下来的两行可能对b和on也能这样做。但是,我不认为这是一个很好的方法。也许递归是个更好的主意

f(P,S),
member(Y,[P]).
我很确定我应该在最后添加一个递归,但我不确定如何实现。有人能帮我吗

(3/4)编辑:

我用下面的@capelical方法成功地解决了单元素列表的问题。但是,我想扩展这个问题,使其适用于多元素列表,其中Prolog事实现在看起来像:

f(a, [b, d]).
f(b, [c]).
f(c, []).
f(d, [e]).
f(e, [f]).
f(f, [g).
f(g, []).
在这种情况下,
xyz(a,X)
的查询应该给我:
X=[b,c,d,e,f,g]
,元素顺序不一定重要,我可以在后面排序

这是以前适用于单个列表的代码:

xyz(Z, [X|Y]):-
    f(Z,[X]),
    !,
    xyz(X,Y).
    xyz(_,[]).
根据@潜伏者的说法,我需要合并成员函数,但我遇到了麻烦。这是我当前的方法,但它不起作用,只给我一个空列表作为所有内容的输出:

xyz(Z, [X|Y]):-
    f(Z,X),
    member(Y,X), // I'm not sure if this should be a 'Y'
    !,
    xyz(X,Y).
    xyz(_,[]).

有什么想法吗?

这段代码按相反的顺序获取列表,请按照您的要求

xyz(K, [D|Ds]) :- f(K, [D]), !, xyz(D, Ds).
xyz(_, []).
编辑扩展到多个依赖项元素(但没有循环!)可以像这样完成

xyz(K, Ds) :- f(K, DKs) -> findall([T|P], (member(T, DKs), xyz(T, P)), L), flatten(L, F), sort(F, Ds) ; Ds = [].

查询
f(X,P,)
将始终失败,因为它与事实
f
的算术不匹配,而事实有两个参数。所以我看不出您当前的
xyz(a,Y)
是如何成功的。检查您正在显示的内容中是否存在印刷错误。@Lower对此表示抱歉。我会更新我的帖子。我期待您的回复,谢谢。如果
P
已经是一个列表,您不需要
成员(Y,[P])
。您需要
成员(Y,P)
。例如,如果
P=[a,b,c]
,那么
成员(Y,[P])
只有在
Y=[[a,b,c]]
时才为真。不是你想要的。如果你做了
成员(Y,P)
,那么
Y=a
Y=b
Y=c
,你为什么在这里做
课程(Z[X])
?记住我们关于列表的讨论:如果希望第二个参数是一个列表,则不要在其周围加上括号作为
[X]
,否则,您将只匹配一个元素的列表,即
X
。您只需要
课程(Z,X)
。另外,事情已经发生了很大的变化,这应该作为一个新问题发布。谢谢,我会研究你的方法。正因为如此,我才发现了用“切割”来控制回溯的想法。我还不知道在一个条件谓词中可以有多个以“.”结尾的表达式。顺便说一下,我不需要按相反的顺序编写代码片段。解决这个问题的快速方法?另外,我注意到,即使这个方法适用于大多数测试场景,但它并不适用于所有测试场景,它会给出一个空列表,而不是正确的答案列表。例如,给出这些序言事实:“f(a,[b,c,d]).f(b,[e]).f(c,[j,g]).f(e,[h]).f(g,[b]).f(j,[b]).f(h,[])。”用你的方法,对于xyz(a,X),我得到X=[],而显然我应该得到一个密集列表。您知道您的代码中是否存在导致这种情况的某些限制吗?谢谢。@am3decoy您的原始问题陈述显示了您的事实的所有单元素列表。您在评论中只提到了多元素列表。所以你原来的问题很不清楚。@lower谢谢你指出这一点。OP只是一个简化版本。列表中可能有多个元素,因此需要回溯该列表中的所有元素。问题是,Capelical的方法仍然适用于多元素列表,但其中一些元素列表并不适用,比如我在您前面的评论中发布的一个元素列表。您知道限制可能在Capelical提供的代码段中的什么地方吗?@am3decoy,
如果元素
X
在列表
L
中,则成员(X,L)
为true。因此,只有当元素
[Z]
在列表
P
中时,
成员([Z],P)
才是真的,这意味着
P=[…,[Z],…]