una programacion listas lista insertar funciones fuente elemento ejemplo conocimiento codigo list prolog

list - programacion - ¿Cómo ''devolver'' un valor en prolog?



programacion en prolog (1)

Lo que intento hacer es agregar elementos de dos listas a otra y al final obtener el valor de la nueva lista en la consola. Mis listas son: A = [a, b]; B (lista de pares) = [(c, cc), (a, aa), (b, bb)] Quiero agregar el segundo elemento del par de la lista B si el primer elemento coincide con el primer elemento del par (diccionario principio) Y quiero que todos esos elementos se agreguen en una lista vacía que la consola generará. Lo que tengo hasta ahora es esto (X sería la lista vacía):

aa(_, [], _) :- true. aa([H|T], [(A, B)|T2], X) :- H == A -> append([B], X, X2), aa([H|T], T2, X2); aa([H|T], T2, X).

En la consola estoy escribiendo: read(X), trace,aa([a, b], [(c, cc), (a, aa), (b, bb)], X), write(X).

Pero sigue devolviendo el valor [] de X. ¿Cómo puedo obtener el valor de X2 como salida si estoy pidiendo X? Aquí está el resultado del rastreo:

Call:aa([a, b], [(c,cc), (a,aa), (b,bb)], []) Call:a==c Fail:a==c Redo:aa([a, b], [(c,cc), (a,aa), (b,bb)], []) Call:aa([a, b], [(a,aa), (b,bb)], []) Call:a==a Exit:a==a Call:lists:append([aa], [], _2110) Exit:lists:append([aa], [], [aa]) Call:aa([a, b], [(b,bb)], [aa]) Call:a==b Fail:a==b Redo:aa([a, b], [(b,bb)], [aa]) Call:aa([a, b], [], [aa]) Exit:aa([a, b], [], [aa]) Exit:aa([a, b], [(b,bb)], [aa]) Exit:aa([a, b], [(a,aa), (b,bb)], []) Exit:aa([a, b], [(c,cc), (a,aa), (b,bb)], []) Call:write([]) [] Exit:write([])


No es una buena idea poner el ; al final de una línea, es muy fácil pasarlo por alto. Prefiero un formato diferente, ver abajo. En cuanto a su pregunta, tiene los argumentos para append/3 en el orden incorrecto. X2 es el resultado intermedio de la llamada recursiva, y el resultado que desea "devolver" es la combinación de este X2 con el elemento B :

aa(_, [], _) :- true. aa([H|T], [(A, B)|T2], X) :- ( H == A -> append([B], X2, X), aa([H|T], T2, X2) ; aa([H|T], T2, X) ).

El append([B], X2, X) objetivo append([B], X2, X) puede escribirse más claramente como X = [B|X2] .

Esto soluciona el problema inmediato, pero aún no todo el predicado:

?- aa([a, b], [(c, cc), (a, aa), (b, bb)], X). X = [aa|_G22] ; false.

Descompones el primer argumento en [H|T] pero no realizas una recursión sobre esta lista, por lo que nunca miras b y su elemento correspondiente en la lista de pares.

Aquí hay una manera simple de hacer todo:

aa([], _Pairs, []). aa([Key|Keys], Pairs, Values) :- ( member((Key, Value), Pairs) -> aa(Keys, Pairs, Values0), Values = [Value|Values0] ; aa(Keys, Pairs, Values) ).

La idea clave aquí es que una vez que conoce una Key , puede buscar un par (Key, Value) en su lista de pares. Value valor aún no está vinculado a un valor y el member/2 creará una instancia si la lista contiene un par cuyo primer elemento es Key . ¡Este es el poder de la unificación!

Esto parece funcionar:

?- aa([a, b], [(c, cc), (a, aa), (b, bb)], X). X = [aa, bb].

Finalmente, es probable que no desee tener una read(X) antes de esto, ya que eso significa que el usuario debe predecir la solución.