我在Prolog很新鲜。我正在尝试编写一个谓词,找到Max值及其整数列表的索引。即MAX=4
将产生INDEX=2
,var markerdata = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-84.537291, 33.767675, 0]
},
"properties": {
"geometry": "Point",
"name": "Test Marker 1",
"url": "http://www.someurl.com/file_1.html"
}
}, {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-84.556685, 33.748580, 0]
},
"properties": {
"geometry": "Point",
"name": "Test Marker 2",
"url": "http://www.someotherurl.com/file_2.html"
}
}]
};
谢谢你的回复〜我道歉!这是我第一次在stackoverflow中提问。我可以编写一个谓词来查找列表的最大值或最小值,但我不知道如何获得列表中值的确切位置。我只是想了解答案。
答案 0 :(得分:4)
使用clpfd ...
:- use_module(library(clpfd)).
我们定义 ...,meta-predicate maplist/2
和nth0/3
:
zs_maximum_at(Zs,Max,Pos) :-
maplist(#>=(Max),Zs),
nth0(Pos,Zs,Max).
这是OP给出的查询:
?- zs_maximum_at([2,3,4],M,I).
I = 2, M = 4.
OK! ... 最常见的查询怎么样?
?- zs_maximum_at(Zs,M,I).
Zs = [M], I = 0, M in inf..sup
; Zs = [ M,_B], I = 0, M #>= _B
; Zs = [_A, M], I = 1, M #>= _A
; Zs = [ M,_B,_C], I = 0, M #>= _B, M #>= _C
; Zs = [_A, M,_C], I = 1, M #>= _A, M #>= _C
; Zs = [_A,_B, M], I = 2, M #>= _A, M #>= _B
; Zs = [ M,_B,_C,_D], I = 0, M #>= _B, M #>= _C, M #>= _D
; Zs = [_A, M,_C,_D], I = 1, M #>= _A, M #>= _C, M #>= _D
...
编辑:算术表达式怎么样?
我们可以通过添加额外目标(#=)/2
来允许使用算术表达式:
zs_maximum_at(Zs,Expr,Pos) :- maplist(#>=(Max),Zs), nth0(Pos,Zs,Expr), Expr #= Max.
现在我们可以运行类似下面的查询 - 但却失去了单调性(参见this clpfd manual)!
?- zs_maximum_at([0+1,1+1,2-0,3-1,1+0],M,I). I = 1, M = 1+1 ; I = 2, M = 2-0 ; I = 3, M = 3-1 ; false.
要禁用算术表达式,我们可以将length/2
与ins/2
结合使用:
zs_maximum_at(Zs,Max,Pos) :- length(Zs,_), Zs ins inf..sup, maplist(#>=(Max),Zs), nth0(Pos,Zs,Max).
再次运行上面的查询,我们现在得到:
?- zs_maximum_at([0+1,1+1,2-0,3-1,1+0],M,I). ERROR: Type error: `integer' expected, found `0+1' (a compound)
请注意,(允许使用算术表达式)的问题不仅限于clpfd。
当使用普通的Prolog算术谓词(如is/2
和朋友)时,它也会出现。
答案 1 :(得分:2)
我自己不是Prolog专家所以这可能不是最美丽的解决方案,但这个谓词应该做你想要的:
max_list([X|Xs],Max,Index):-
max_list(Xs,X,0,0,Max,Index).
max_list([],OldMax,OldIndex,_, OldMax, OldIndex).
max_list([X|Xs],OldMax,_,CurrentIndex, Max, Index):-
X > OldMax,
NewCurrentIndex is CurrentIndex + 1,
NewIndex is NewCurrentIndex,
max_list(Xs, X, NewIndex, NewCurrentIndex, Max, Index).
max_list([X|Xs],OldMax,OldIndex,CurrentIndex, Max, Index):-
X =< OldMax,
NewCurrentIndex is CurrentIndex + 1,
max_list(Xs, OldMax, OldIndex, NewCurrentIndex, Max, Index).
答案 2 :(得分:2)
joel76的一个变种回答:
max_list(L, M, I) :- nth0(I, L, M), \+ (member(E, L), E > M).
答案 3 :(得分:1)
另一种方法,效率不高但更多&#34; prologish&#34;是说: 列表的最大值是多少?它是列表的成员,此列表中没有其他成员大于最大值! 所以:
max_list(Lst, Max, Ind) :-
member(Max, Lst),
\+((member(N, Lst), N > Max)),
% Now, with SWI-Prolog, (may be with other Prolog)
% nth0/3 gives you the index of an element in a list
nth0(Ind, Lst, Max).