2010-12-07 18 views
7

estoy empezando a jugar con prólogo, y con un fondo de Java es muy difícil para mí, así que aquí hay una pregunta tonta:¿Cómo se calcula el índice del elemento en una lista?

¿Cómo va a escribir un predicado indexOf capaz de dar el índice de un elemento dado en un determinado lista?

Mi primera pregunta es sobre la aridad predicado: supongo que debe ser de 3, tales como:

indexOf(List,Element, Index) :- ...... 

Estoy en lo cierto? Puede que esto ya exista en las bibliotecas integradas, pero quiero aprender a escribirlo. Gracias por tu ayuda.

+0

parece un buen comienzo. – aschepler

+0

@aschepler sí, pero me estoy volviendo loco tener este pequeño predicado funcionando !!! –

+0

Este es de hecho un buen ejercicio al aprender prólogo. FYI: los predicados de construcción para lograr esto son 'nth0' y' nth1'. (http://www.swi-prolog.org/pldoc/doc_for?object=section%282,%27A.12%27,swi%28%27/doc/Manual/lists.html%27%29%29) – Cephalopod

Respuesta

11

Puede hacerlo de forma recursiva: Supongamos índice basado en 0 (de lo contrario sólo cambiar el 0 con 1 en la primera cláusula)

indexOf([Element|_], Element, 0). % We found the element 
indexOf([_|Tail], Element, Index):- 
    indexOf(Tail, Element, Index1), % Check in the tail of the list 
    Index is Index1+1. % and increment the resulting index 

Si desea sólo para encontrar la primera aparición, se podría añadir un recorte (!) para evitar retroceder.

indexOf([Element|_], Element, 0):- !. 
indexOf([_|Tail], Element, Index):- 
    indexOf(Tail, Element, Index1), 
    !, 
    Index is Index1+1. 
+0

gracias por la respuesta. ¿Puedo reemplazar la primera cláusula con: indexOf ([First | _], Element, Index): - Primero == Element, Index == 0.? –

+0

La respuesta es NO. Puedes explicar porque ? –

+0

El operador == no realiza la unificación. Por lo tanto, no puede crear una instancia de Index en 0. Sin embargo, puede usarse en la primera comparación (First == Element estaría bien porque en ese predicado se deben instanciar ambos términos). Index == 0 fallará cuando Index no se instancia. – gusbro

1

Uno debe preferir el uso de cola de recursión:

indexOf(V, [H|T], A, I) 
:- 
    Value = H, A = I, ! 
; 
    ANew is A + 1, 
    indexOf(V, T, ANew, I) 
. 

indexOf(Value, List, Index) 
:- 
    indexOf(Value, List, 0, Index) 
. 

indexOfWithoutFailure(Value, List, Index) 
:- 
    indexOf(Value, List, 0, Index) 
; 
    Index = -1 
. 

Algunas consultas de ejemplo:

?- indexOf(d, [a, b, c, d, e, f], Index). 
Index = 3. 

?- indexOf(x, [a, b, c, d, e, f], Index). 
false. 

?- indexOfWithoutFailure(x, [a, b, c, d, e, f], Index). 
Index = -1. 

Si desea obtener todos los índices de un elemento en una lista, usted debe escriba otro predicado sin el corte llamado allIndexesOf o algo así.

0

Hice esto en notación sucesor y es muy concisa y ordenada: salidas

index([V|_],V,0). 
index([_|T],V,s(I)) :- index(T,V,I). 

de muestra:

?- index([a,b,c,a],a,X). 
X = 0 ; 
X = s(s(s(0))) ; 
false. 

?- index(List,a,s(0)). 
List = [_G1710, a|_G1714]. 
Cuestiones relacionadas