List 在Prolog中通过索引从i到j获取原子列表

List 在Prolog中通过索引从i到j获取原子列表,list,split,prolog,List,Split,Prolog,我想从我的原子列表中得到一个原子列表,这个列表基于给定的索引从I到索引从I到j。我尝试了很多次,但它没有返回我的列表,但下面的“true”是我的代码,我错过了什么?如何获取输出列表而不是“true” % splitList(INPUT_LIST, INDEX_FROM, INDEX_TO, INDEX_FROM, OUTPUTLIST). splitList(INPUT_LIST,INDEX_FROM,INDEX_TO, S,LIST) :- INPUT_LIST = INPUT_LIS

我想从我的原子列表中得到一个原子列表,这个列表基于给定的索引从I到索引从I到j。我尝试了很多次,但它没有返回我的列表,但下面的“true”是我的代码,我错过了什么?如何获取输出列表而不是“true”

% splitList(INPUT_LIST, INDEX_FROM, INDEX_TO, INDEX_FROM, OUTPUTLIST).
splitList(INPUT_LIST,INDEX_FROM,INDEX_TO, S,LIST) :-
    INPUT_LIST = INPUT_LIST,
    S = S,
    INDEX_FROM =:= INDEX_TO + 1,
    write(LIST),
    LIST = LIST.
splitList(INPUT_LIST,INDEX_FROM,INDEX_TO,S,LIST) :-
    INDEX_FROM < INDEX_TO + 1,
    nth0(INDEX_FROM, INPUT_LIST, ELEMENT),
    (  INDEX_FROM =:= S ->
    L = []
    ;   
    L = LIST
    ),
    IF is INDEX_FROM + 1,
    append([ELEMENT],L,NLIST),
    splitList(INPUT_LIST,IF,INDEX_TO,S,NLIST),
    !.

?- splitList(['TYPE_INT', 'IDENTIFIER', 'OPEN_P', 'TYPE_INT', 'IDENTIFIER', 'COMMA'],0,3,0,L).
?- true.

My atom list: ['TYPE_INT', 'IDENTIFIER', 'OPEN_P', 'TYPE_INT', 'IDENTIFIER', 'COMMA'],

if index_from is 1, index_to is 3, I am expecting a returned output_list:
['TYPE_INT', 'IDENTIFIER', 'OPEN_P', 'TYPE_INT'] instead of a 'true', 
%splitList(输入列表、索引自、索引至、索引自、输出列表)。
拆分列表(输入列表、索引自、索引至、列表):-
输入列表=输入列表,
S=S,
INDEX_FROM=:=INDEX_TO+1,
写(列表),
列表=列表。
拆分列表(输入列表、索引自、索引至、列表):-
索引从<索引到+1,
nth0(索引来源、输入列表、元素),
(索引从=:=S->
L=[]
;   
L=列表
),
如果索引_来自+1,
追加([ELEMENT],L,NLIST),
拆分列表(输入列表、IF、索引到、S、NLIST),
!.
?-拆分列表(['TYPE_INT','IDENTIFIER','OPEN_P','TYPE_INT','IDENTIFIER','COMMA'],0,3,0,L)。
-是的。
我的原子列表:['TYPE_INT','IDENTIFIER','OPEN_P','TYPE_INT','IDENTIFIER','COMMA'],
如果index_from为1,index_to为3,我希望返回一个输出列表:
['TYPE_INT'、'IDENTIFIER'、'OPEN_P'、'TYPE_INT']而不是'true',

在我的基本情况下,“write(LIST)确实写了期望的LIST”,你知道吗?

你可以不用cut来写这样一个谓词。想想你的谓词应该描述什么:一个列表,一些开始、结束和当前位置的索引,以及适合你的开始和结束索引的第一个列表的子列表。所以列表索引子列表可能是个好名字。现在考虑你可以拥有什么样的情况:

如果当前位置和结束位置相同,则第一个列表的标题是子列表中的最后一个:

list_indices_sublist([X|_Xs],_Start,End,End,[X]).
list_sublist_from_to(['TYPE_INT', 'IDENTIFIER', 'OPEN_P', 'TYPE_INT', 'IDENTIFIER', 'COMMA'] ,L,1,3).
L = ['TYPE_INT','IDENTIFIER','OPEN_P'] ? ;
no 
如果当前位置在起始位置和结束位置之间,则第一个列表的标题位于子列表中。对于两个列表的尾部,关系(=谓词)也必须保持(=递归):

或1到3以及子列表中包含3个元素的答案:

list_indices_sublist([X|_Xs],_Start,End,End,[X]).
list_sublist_from_to(['TYPE_INT', 'IDENTIFIER', 'OPEN_P', 'TYPE_INT', 'IDENTIFIER', 'COMMA'] ,L,1,3).
L = ['TYPE_INT','IDENTIFIER','OPEN_P'] ? ;
no 

注意:如果您想开始用0而不是1来计算列表位置,只需首先将列表子列表的第二个目标中的1从\u更改为/4,您应该注意Prolog不是基于赋值,而是基于统一。那么比如说,

INPUT_LIST = INPUT_LIST,
是重言式(将相同的术语与其自身统一起来,始终正确)。您可以安全地移除它们

其次,您的代码有一个附加参数
S
,该参数没有明确的角色。可能是您尝试实现的剩余细节,但实际上应该“隐藏”,例如:

% splitList(INPUT_LIST, INDEX_FROM, INDEX_TO, OUTPUTLIST).
splitList(INPUT_LIST, INDEX_FROM, INDEX_TO, LIST) :-
  splitList(INPUT_LIST, INDEX_FROM, INDEX_TO, 0, LIST).
第三,谓词最后一个子句末尾的cut是完全无用的,因为所有的选择都已经尝试过了——并且成功了。没有什么可以切割的了

第四,由于您使用内置的nth0/3,请注意,可以使用更简单的实现

splitList(INPUT_LIST,INDEX_FROM,INDEX_TO, LIST) :-
  findall(E, (between(INDEX_FROM,INDEX_TO,I),nth0(I,INPUT_LIST,E)), LIST).

?- splitList(['TYPE_INT', 'IDENTIFIER', 'OPEN_P', 'TYPE_INT', 'IDENTIFIER', 'COMMA'],0,3,L).
L = ['TYPE_INT', 'IDENTIFIER', 'OPEN_P', 'TYPE_INT'].
但是,让我们尝试更正您的代码。可能是

splitList(INPUT_LIST,INDEX_FROM,INDEX_TO, LIST) :-
  splitList(INPUT_LIST,INDEX_FROM,INDEX_TO, 0, LIST).

splitList(INPUT_LIST,INDEX_FROM,INDEX_TO, S,LIST) :-
  S < INDEX_FROM,
  S1 is S+1,
  splitList(INPUT_LIST,INDEX_FROM,INDEX_TO, S1,LIST).
splitList(INPUT_LIST,INDEX_FROM,INDEX_TO, S,[ELEMENT|LIST]) :-
  S >= INDEX_FROM, S =< INDEX_TO,
  nth0(S, INPUT_LIST, ELEMENT),
  S1 is S+1,
  splitList(INPUT_LIST,INDEX_FROM,INDEX_TO, S1,LIST).
splitList(_INPUT_LIST,_INDEX_FROM,INDEX_TO, S,[]) :-
  S > INDEX_TO.
splitList(INPUT_LIST,INDEX_FROM,INDEX_TO, LIST) :-
  findall(E, (between(INDEX_FROM,INDEX_TO,I),nth0(I,INPUT_LIST,E)), LIST).

?- splitList(['TYPE_INT', 'IDENTIFIER', 'OPEN_P', 'TYPE_INT', 'IDENTIFIER', 'COMMA'],0,3,L).
L = ['TYPE_INT', 'IDENTIFIER', 'OPEN_P', 'TYPE_INT'].
splitList(INPUT_LIST,INDEX_FROM,INDEX_TO, LIST) :-
  splitList(INPUT_LIST,INDEX_FROM,INDEX_TO, 0, LIST).

splitList(INPUT_LIST,INDEX_FROM,INDEX_TO, S,LIST) :-
  S < INDEX_FROM,
  S1 is S+1,
  splitList(INPUT_LIST,INDEX_FROM,INDEX_TO, S1,LIST).
splitList(INPUT_LIST,INDEX_FROM,INDEX_TO, S,[ELEMENT|LIST]) :-
  S >= INDEX_FROM, S =< INDEX_TO,
  nth0(S, INPUT_LIST, ELEMENT),
  S1 is S+1,
  splitList(INPUT_LIST,INDEX_FROM,INDEX_TO, S1,LIST).
splitList(_INPUT_LIST,_INDEX_FROM,INDEX_TO, S,[]) :-
  S > INDEX_TO.
?- splitList(['TYPE_INT', 'IDENTIFIER', 'OPEN_P', 'TYPE_INT', 'IDENTIFIER', 'COMMA'],0,10,L).
false.