Prolog内部变量名称

时间:2017-06-25 18:52:36

标签: prolog

我的文件(position(M,P))中已有大量事实,M是名称,P是玩家的位置,我被要求做player_list(L,N),L是球员列表和N是此列表的大小。我做到了它的工作问题是,它给出的列表没有名称,它给我数字而不是名称

player_list([H|T],N):-  L = [H|T],
                   position(H,P),
                   \+ member(H,L),
                   append(L,H),
                   player_list(T,N).

我得到的是:

?- player_list(X,4).
  X = [_9176, _9182, _9188, _9194] .

那我该怎么办?

1 个答案:

答案 0 :(得分:4)

您可以使用其他列表作为参数来跟踪您已有的玩家。此列表在开头是空的,因此调用谓词调用描述与[]的实际关系的谓词作为附加参数:

player_list(PLs,L) :-
   pl_l_(PLs,L,[]).            % <- actual relation

您发布的定义缺少基本情况,也就是说,如果您已经拥有所需数量的玩家,则可以停止添加其他玩家。在这种情况下,要添加的玩家数量为零,否则大于零。你还必须描述列表的头部(PL)是一个玩家(你不关心它的位置,所以变量前面有一个下划线(_P),否则就是目标就像在你的代码中一样)并且还没有在累加器中(与你的代码相反,你检查PL是否不在L中)但是在递归调用中它在累加器中。您可以通过在递归目标中使用[PL|Acc0]来实现后者,因此您不需要append/2。将所有这些放在一起,您的代码可能如下所示:

pl_l_([],0,_).                % base case
pl_l_([PL|PLs],L1,Acc0) :-
   L1 > 0,                    % number of players yet to add
   L0 is L1-1,                % new number of players to add
   position(PL,_P),           % PL is a player and
   \+ member(PL,Acc0),        % not in the accumulator yet
   pl_l_(PLs,L0,[PL|Acc0]).   % the relation holds for PLs, L0 and [PL|Acc0] as well

关于你的评论,我认为你的代码包含以下四个事实:

position(zlatan,center).
position(rooney,forward).
position(ronaldo,forward).
position(messi,forward).

然后您的示例查询会产生所需的结果:

   ?- player_list(X,4).
X = [zlatan,rooney,ronaldo,messi] ? ;
X = [zlatan,rooney,messi,ronaldo] ? ;
...

如果你打算反过来使用谓词,我建议使用CLP(FD)。要了解原因,请考虑最常见的查询:

   ?- player_list(X,Y).
X = [],
Y = 0 ? ;
     ERROR at  clause 2 of user:pl_l_/3 !!
     INSTANTIATION ERROR- =:=/2: expected bound value

您收到此错误是因为>/2期望两个参数都被接地。您可以修改谓词pl_l_/3以使用CLP(FD),如下所示:

:- use_module(library(clpfd)).

pl_l_([],0,_).
pl_l_([PL|PLs],L1,Acc0) :-
   L1 #> 0,                    % <- new
   L0 #= L1-1,                 % <- new
   position(PL,_P),
   \+ member(PL,Acc0),
   pl_l_(PLs,L0,[PL|Acc0]).

通过这些修改,谓词更加通用:

   ?- player_list([zlatan,messi,ronaldo],Y).
Y = 3

   ?- player_list(X,Y).
X = [],
Y = 0 ? ;
X = [zlatan],
Y = 1 ? ;
X = [zlatan,rooney],
Y = 2 ?
...