Prolog 内部变量名

标签 prolog

我的文件 (position(M,P)) 中已有大量事实,M 是玩家的名字,P 是玩家的位置,我被要求做a 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] .

那我该怎么办?

最佳答案

您可以使用附加列表作为参数来跟踪您已有的玩家。这个列表一开始是空的,所以调用谓词调用描述与 [] 的实际关系的谓词作为附加参数:

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

关于Prolog 内部变量名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44749504/

相关文章:

list - Prolog:过滤列表?

prolog - 如何将整数创建为字符代码常量?

prolog - 序言中的合取与析取优先级

prolog - Prolog 中的自恋数

Prolog:如何获得最年长和最年轻的血统

c# - SWI-prolog 到 C# 断言不工作

prolog - 为什么SWI-Prolog只给出一种解决方案?

prolog - 在列表中查找最大值 - Prolog

Prolog:将列表向右旋转 n 次

list - 将元素添加到子列表