我是prolog的新手,我处于解决一个问题的边缘,但是当我试图退出递归并将列表返回到初始函数时,我遇到了问题。你能帮帮我吗?我整天都在苦苦挣扎。感谢
以下是我构建列表时最终会发生的事情:
以下是我的谓词:
depth_first(N, ReturnList) :-
df_real(2:1, N, [2:1], ReturnList).
df_real(_:NextRankC, Size, Q, ReturnList) :-
genInt(Size, Row),
Column is NextRankC + 1,
Rank = Row:Column,
not(list_attack(Rank, Q)),
add(Rank, Q, NewList),
df_real(1:Column, Size, NewList, NewList).
% Recursive Case: Exit when list is full.
df_real(_, N, Q, Newlist) :- length(Q, Length),
N = Length.
调用谓词:
depth_first(4,Q)。
注意:假设genInt/2
,add/3
和list_attack/2
工作正常,我的问题最终只是删除了我刚刚构建的所有元素并返回了一些变量,它必须返回列表而不是true。
更新当我使用
时 df_real(_:NextRankC, Size, Q, NewList) :-
...
df_real(1:Column, Size, NewList, NewList).
跟踪 - 失败,因为NewList现在是一个List而不是要添加到列表中的变量。
答案 0 :(得分:1)
最终,代码的问题是您需要设置适当的模式来返回列表。 Prolog中的一个常见模式是传入一个通过所有递归传递的变量参数,并最终在终端案例中实例化。该变量最初在第一个子句中设置。
depth_first(N, ReturnList) :-
df_real(2:1, N, [2:1], ReturnList).
所以这里第一个查询是以第四个参数作为返回答案列表的变量ReturnList
启动的。到目前为止,非常好。
df_real(_:NextRankC, Size, Q, ReturnList) :-
genInt(Size, Row),
Column is NextRankC + 1,
Rank = Row:Column,
not(list_attack(Rank, Q)),
add(Rank, Q, NewList),
df_real(1:Column, Size, NewList, NewList).
最初,你有_
作为第四个参数,这是不正确的,因为你需要第四个参数作为一个变量,你可以在其中返回答案。现在将第4个参数设置为ReturnList
是好的,但是当前没有调用此子句的实例将其调用。因此,您的跟踪显示_XXXX
的值(它未经实例化)。最后一个问题是问题:
df_real(1:Column, Size, NewList, NewList).
出于某种原因,你有NewList
作为第3和第4个参数。您可能希望ReturnList
作为第4个参数,以便它通过递归进行并最终设置:
df_real(1:Column, Size, NewList, ReturnList).
最后,终端(或基地)案例:
% Recursive Case: Exit when list is full.
df_real(_, N, Q, Newlist) :-
length(Q, Length),
N = Length.
NewList
这里的第四个参数什么也没做。它是一个单例变量,并没有被任何东西填充。因此,在跟踪中,它会显示为_XXXX
,并且您在ReturnList
中没有答案。当Q
列表已达到N
时,表示您已完成该条款。我想,在那时,Q
是你想要的答案。所以你只需要在Prolog中这样说:
% Recursive Case: When list is full, it's the answer
df_real(_, N, Q, Q) :-
length(Q, N).
你也可以通过简化第一个参数来整理一下。它是X:Y
形式的术语,您永远不会使用X
,为什么要随身携带?
depth_first(N, ReturnList) :-
df_real(1, N, [2:1], ReturnList).
df_real(_:NextRankC, Size, Q, ReturnList) :-
genInt(Size, Row),
Column is NextRankC + 1,
Rank = Row:Column,
\+ list_attack(Rank, Q), % Note use of ISO negation predicate, \+
add(Rank, Q, NewList),
df_real(Column, Size, NewList, ReturnList).
% Recursive Case: When list is full, it's the answer
df_real(_, N, Q, Q) :-
length(Q, N).