我如何编写一个谓词list_pos(B,E,L)
,它返回E
中B
的位置,位于名为L
的列表中(考虑B
的第一个元素1}}有位置= 0),我尝试编写这样的程序,但它没有成功运行。谢谢
答案 0 :(得分:2)
这是一个比@ Jerome更为通用的解决方案:
", "
所以你甚至不需要指出你想要的精确元素。相反,你问:
各种元素的出现次数是什么?
这甚至可以进一步推广......
答案 1 :(得分:2)
这是一个通用的,纯粹的解决方案 - 我将在这里放置一个赏金以使其适合更方便的抽象。
list_pos(Xs, E, Ps) :-
list_pos(Xs, E, Ps, 0).
list_pos([], _E, [], _P).
list_pos([X|Xs], X, [P0|Ps], P0) :-
P1 is P0 + 1,
list_pos(Xs, X, Ps, P1).
list_pos([X|Xs], E, Ps, P0) :-
dif(X, E), % element must be different
P1 is P0 + 1,
list_pos(Xs, X, Ps, P1).
这是list_pos/4
使用if_/3
和重新平等(=)/3
的更紧凑和有效的方法。 Prolog的if_/3
与传统的if-then-else略有不同,因为它可以选择 然后和 Else。也许只需试用if_/3
:
?- if_( X=Y, Diagnosis=equal, Diagnosis=inequal).
X = Y,
Diagnosis = equal ;
Diagnosis = inequal,
dif(X, Y).
非正式地,我们在这里问的是:
X
和Y
是否相等?
而Prolog的回答不仅仅是肯定或否定,而是:
是的,如果他们是平等的,他们是平等的
和强>
不,他们不平等,如果他们不同
听起来很烦人?好吧,如果我们问这些一般性问题不包含足够的信息,我们不应该对得到类似的一般答案感到惊讶!
list_pos([], _E, [], _P).
list_pos([X|Xs], E, Ps0, P0) :-
P1 is P0+1,
if_(X = E, Ps0 = [P0|Ps1], Ps0 = Ps1),
list_pos(Xs, E, Ps1, P1).
现在,让我们尝试一些非常通用的东西!
列表
[X,Y,Z]
的外观必须如此,以便任何元素E
出现在其中两次?
?- list_pos([X,Y,Z],E,[A,B]).
X = Y, Y = E, % ... the first two are the same
A = 0, B = 1,
dif(Z, E) % ... but the last is different
; X = Z, Z = E, % ... the first and last are the same
A = 0, B = 2,
dif(Y, E) % ... but the middle element is different
; Y = Z, Z = E, % ... the last two are the same
A = 1, B = 2,
dif(X, E) % ... and the first is different.
; false.
请注意,这些答案包含所有可能的三个元素列表的完整通用性!所有这些都已包括在内。
答案 2 :(得分:1)
感谢@false和@Jerome,我学到了很多东西。不过,我会发布我的努力:
list_pos(List,Elem,Result) :-
list_pos(List,Elem,[],-1,R),
reverse(R,Result),
!.
list_pos([],_,W,_,W).
list_pos([X|Xs],X,Zs,P,R) :-
Pos is P + 1,
list_pos(Xs,X,[Pos|Zs],Pos,R).
list_pos([_|Xs],Y,Zs,P,R) :-
Pos is P + 1,
list_pos(Xs,Y,Zs,Pos,R).
实施例
?- list_pos([],a,R).
R = [].
?- list_pos([a,c,a,d,e,f],a,R).
R = [0, 2].
?- list_pos([a,b,c,d,e,f,g],g,R).
R = [6].
?- list_pos([a,a,a,a,a,a,a,a,a],a,R).
R = [0, 1, 2, 3, 4, 5, 6, 7, 8].
答案 3 :(得分:0)
我试过了:
list_pos(1,Match,[Match|_]).
list_pos(Pos,Element,[_|Tail]) :-
list_pos(P,Element,Tail),
Pos is P + 1.
实施例
?- list_pos(B,a,[a]).
B = 1 .
?- list_pos(B,a,[b,a]).
B = 2 .
?- list_pos(B,a,[b,c,d,e,a,f]).
B = 5 .
答案 4 :(得分:0)
要构建所有结果的列表,请使用findall
:
list_pos(List, Element, Result) :-
findall(Position, nth0(Position, List, Element), Result).