我需要获取列表中所有正元素的每个索引,并使用所有这些索引创建一个新列表
例如
[-1,2,-5] -> [1]
[1,2,-5] -> [0,1]
我已经有了一个获取索引的谓词,但我不明白如何遍历每个值并在最后返回一个列表。现在我的谓词看起来像
indexOf([Element|_], Element, 0) :- !.
indexOf([_|Tail], Element, Index) :-
indexOf(Tail, Element, Index1),
!,
Index is Index1+1.
iterate([],Res) :- Res.
iterate([H|T],Res) :-
H>0,
indexOf([H|T],H,Ind),
append([],[Ind],Res),
iterate(T,Res).
iterate([H|T],Res) :-
H=<0,
iterate(T,Res).
但编译后,我收到此错误
**Input**
iterate([-1,-2,3],X).
**Output**
Sandbox restriction!
Could not derive which predicate may be called from
call(C)
iterate([],A)
iterate([3],A)
iterate([-2,3],A)
iterate([-1,-2,3],A)
请告诉我,我做错了什么?以及为什么会出现这个错误
答案 0 :(得分:1)
您错误地使用了 Prolog:
iterate([],Res) :- Res.
将调用绑定到 Res
的术语(希望是谓词的名称),但不会返回 Res
。
SWISH 不会让您执行无法确定它们是否安全的疯狂调用,因此会出现错误。
但是为什么这么复杂的代码呢?按规定做:
% ---
% gimme_positives(List,Positive)
% gimme_positives_2(Idx,List,Positive)
% ---
% We call this
gimme_positives(List,Indexes) :-
gimme_positives_2(0,List,Indexes).
% This is the "helper" which additionally needs an index
gimme_positives_2(_,[],[]). % If List empty, we are done.
gimme_positives_2(Idx,[L|Ls],[Idx|More]) :- % Case of L positive
L >= 0,
IdxPlus is Idx+1,
gimme_positives_2(IdxPlus,Ls,More). % recursive call
gimme_positives_2(Idx,[L|Ls],More) :- % Case of L negative
L < 0,
IdxPlus is Idx+1,
gimme_positives_2(IdxPlus,Ls,More). % recursive call
那么:
?- gimme_positives([],X).
X = [] ;
false.
?- gimme_positives([-1,2,-5],X).
X = [1] ;
false.
?- gimme_positives([1,2,-5],X).
X = [0,1] ;
false.
这实际上是 foldl/4
的情况……一旦您对高阶谓词和组合列表感到宾至如归:
gimme_positives_foldl(List,Indexes) :-
foldl(
selector,
List, % the list of integers
[0,Indexes], % the initial value: index 0 as first, and the RESULT list as second element
[_FinalIndex,[]]). % the final value: an index we don't care about and the termination of the result list: []
selector(L,[Idx,[Idx|More]],[IdxPlus,More]) :-
L >= 0,
IdxPlus is Idx+1.
selector(L,[Idx,More],[IdxPlus,More]) :-
L < 0,
IdxPlus is Idx+1.
我什至无法完全解释为什么我会这样写。
但它有效:
?- gimme_positives_foldl([],X).
X = [].
?- gimme_positives_foldl([-1,2,-5],X).
X = [1] ;
false.
?- gimme_positives_foldl([1,2,-5],X).
X = [0,1] ;
false
答案 1 :(得分:0)
在 SWI-Prolog 中,您可以使用谓词 nth0/3
和 findall/3
:
positive_element_indexes(List, Indexes) :-
findall(Index,
(nth0(Index, List, Element), Element > 0),
Indexes).
一些例子:
?- positive_element_indexes([1,-2,3,-4,5], Indexes).
Indexes = [0, 2, 4].
?- positive_element_indexes([-1,-2,3], Indexes).
Indexes = [2].
?- positive_element_indexes([-1,2,3], Indexes).
Indexes = [1, 2].
?- positive_element_indexes([-1,-2,-3], Indexes).
Indexes = [].