Prolog 序言->;我有一个列表[X,…,Y,…,Z],如何得到一个只从X到Y的列表?

Prolog 序言->;我有一个列表[X,…,Y,…,Z],如何得到一个只从X到Y的列表?,prolog,Prolog,SWI-PROLOG. 我有一个列表[X,…,Y,…,Z],如何得到一个只从X到Y的列表? 也就是[X,…,Y,…,Z]>[X,…,Y] 我对这门语言几乎一无所知,所以欢迎大家的帮助 我试过这个: bla([Ele|_], Ele, _). bla([H|T], Ele, Res):- append(Res, H, New_Res), bla([T], Ele, New_Res). 这里,Ele将是Y. 我将Res初始化为一个空列表 我再说一遍,我对这门语言还不熟悉,所以我写

SWI-PROLOG.
我有一个列表[X,…,Y,…,Z],如何得到一个只从X到Y的列表?
也就是[X,…,Y,…,Z]>[X,…,Y]
我对这门语言几乎一无所知,所以欢迎大家的帮助
我试过这个:

bla([Ele|_], Ele, _). 
bla([H|T], Ele, Res):-
   append(Res, H, New_Res),
   bla([T], Ele, New_Res).  
这里,
Ele
将是Y.
我将
Res
初始化为一个空列表

我再说一遍,我对这门语言还不熟悉,所以我写的可能是非常错误的,对不起

使用它可能只是:

bla(L, Ele, NL):-
  append(NL1, [Ele|_], L),
  append(NL1, [Ele], NL).
注意,
append(L1,L2,L3)
成功当L3是L1和L2的串联时,您可以使用第一个append(
append(NL1,[Ele | |,L)]
)将项目从L提取到所需的项目,其中在本例中,L2是以元素
Ele
开头的列表,因此,L是一个以NL1开头的列表,L的下一个元素是Ele

第二个附加用于将Ele添加到NL1的末尾

不使用
append/3
您可以编写:

bla([Ele|_], Ele, [Ele]).
bla([E|L], Ele, [E|NL]):-
  bla(L, Ele, NL).

如果Ele在L中出现多次,则两种实现可能会多次成功;如果Ele不在L中出现,则两种实现都会失败。

或者,由于谓词描述的是两个列表和枢轴元素之间的关系,因此您可以选择使用DCGs执行任务:

list_pivot_sublist(L,P,S) :-
   phrase(sublist_till(L,P),S).  % the sublist up to the pivot element
                                 % is described by the DCG sublist_till//2

sublist_till([P|_],P) -->        % if the head of the list is P
   [P].                          % it's the last element in the sublist
sublist_till([X|Xs],P) -->       % if the head of the list is any element X
   [X],                          % X is in the sublist and
   sublist_till(Xs,P).           % the same goes for the tail and P
现在我们来看一些查询:

[1,2,3,4,5]到元素3的子列表是什么

[1,2,3,4,5]有哪些子列表枢轴对

对于子列表[1,2,3],原始列表和fitting pivot元素会是什么样子

或者最一般的查询:有哪些对应的列表、透视元素和子列表

这些答案与@gusbro版本的
bla/3
得到的答案相同,但此查询除外

?- bla(L,P,[1,2,3]).
L = [1, 2, 3|_G4739],
P = 3 ;

ERROR: Out of global stack
。。。在给出唯一答案后,循环使用第一个版本(其中有两个
append/3
作为目标)。原因是第一个目标提供了无限多的候选解决方案

?- append(NL1, [Ele|_], L).
NL1 = [],
L = [Ele|_G900] ;
NL1 = [_G1000],
L = [_G1000, Ele|_G900] ;
NL1 = [_G1000, _G1006],                                   % this candidate leads to
L = [_G1000, _G1006, Ele|_G900] ;                         % the only solution
NL1 = [_G1000, _G1006, _G1012],
L = [_G1000, _G1006, _G1012, Ele|_G900] ;
.
.
.
。。。除上述查询中标记的一项外,其他所有操作均失败:

?- append(NL1, [Ele|_], L), append(NL1, [Ele], [1,2,3]).
NL1 = [1, 2],                                             % corresponding answer
Ele = 3,                                                  % to the third candidate
L = [1, 2, 3|_G4641] ;                                    % above
ERROR: Out of global stack
因此,非
append/3
版本显然更可取。关于@Lougler的评论,我还想指出,在这些版本中,如果pivot元素在列表中出现多次,您将得到多个答案:

?- list_pivot_sublist([1,2,3,4,5,3],3,S).
S = [1, 2, 3] ;
S = [1, 2, 3, 4, 5, 3] ;
如果只想获得第一个子列表,可以通过添加约束来更改DCG版本,
X
不同于
p
,该约束可防止Prolog在第一次成功后进一步递归:

sublist_till([P|_],P) -->
   [P].
sublist_till([X|Xs],P) -->
   {dif(X,P)},                % <- new constraint
   [X],
   sublist_till(Xs,P).
最一般的查询也略有不同,因为现在它将
dif/2
约束传播到答案:

?- list_pivot_sublist(L,P,S).
L = [P|_G4739],
S = [P] ;
L = [_G4886, P|_G4890],
S = [_G4886, P],
dif(_G4886, P) ;
L = [_G4942, _G4945, P|_G4949],
S = [_G4942, _G4945, P],
dif(_G4942, P),
dif(_G4945, P) ;
.
.
.
您可以通过向递归规则添加相同的约束来改变@gusbro的第二个版本,使其具有相同的行为:

bla([Ele|_], Ele, [Ele]).
bla([E|L], Ele, [E|NL]):-
  dif(E,Ele),                  % <- new constraint
  bla(L, Ele, NL).
bla([Ele | |,[Ele])。
bla([E|L],Ele[E|NL]):-

dif(E,Ele),%%难道不是已经给了你想要的吗

?- append(L, [y|_], [x,x,x,y,x,y,x,z]).
L = [x, x, x] ;
L = [x, x, x, y, x] ;
false.
您可以通过另一个对
append/3
的调用重新添加最后一个“y”元素:

?- append(L, [y|_], [x,x,x,y,x,y,x,z]), append(L, [y], L1).
L1 = [x, x, x, y] ;
L1 = [x, x, x, y, x, y] ;
false.

这是家庭作业吗?如果你有,
[X,…,Y,…,Y,…,Z]
?您希望最多使用第一个
Y
还是最后一个
Y
?或者你想让每一个都成为一个可能的解决方案?@潜伏者这是我在大学任务中需要的东西。这只是大问题的一小部分。列表中的元素没有重复,所以只有一个Y。非常感谢,它成功了!你能解释一下第一个是如何工作的吗?@TomásGomes:对答案做了一些解释
?- list_pivot_sublist([1,2,3,4,5,3],3,S).
S = [1, 2, 3] ;
false.
?- list_pivot_sublist(L,P,S).
L = [P|_G4739],
S = [P] ;
L = [_G4886, P|_G4890],
S = [_G4886, P],
dif(_G4886, P) ;
L = [_G4942, _G4945, P|_G4949],
S = [_G4942, _G4945, P],
dif(_G4942, P),
dif(_G4945, P) ;
.
.
.
bla([Ele|_], Ele, [Ele]).
bla([E|L], Ele, [E|NL]):-
  dif(E,Ele),                  % <- new constraint
  bla(L, Ele, NL).
?- append(L, [y|_], [x,x,x,y,x,y,x,z]).
L = [x, x, x] ;
L = [x, x, x, y, x] ;
false.
?- append(L, [y|_], [x,x,x,y,x,y,x,z]), append(L, [y], L1).
L1 = [x, x, x, y] ;
L1 = [x, x, x, y, x, y] ;
false.